Git Product home page Git Product logo

marksman's Introduction

Build & Test release homebrew marksman Downloads

Marksman

Write Markdown with code assist and intelligence in the comfort of your favourite editor.

splash


Marksman is a program that integrates with your editor to assist you in writing and maintaining your Markdown documents. Using LSP protocol it provides completion, goto definition, find references, rename refactoring, diagnostics, and more. In addition to regular Markdown, it also supports wiki-link-style references that enable Zettelkasten-like1, 2 note taking. See more about Marksman's features below.

Marksman works on MacOS, Linux, and Windows and is distributed as a self-contained binary for each OS.

The server provides assistance with:

  • Markdown inline links:
    This is [inline link](/some-file.md#some-heading).
    This is an internal [anchor link](#heading).
  • Markdown reference links:
    See [reference].
    
    [reference]: /url "Title"
  • Wiki-links:
    Link to [[another-note]].
    Link to [[another-notes#heading]].
    Internal link to [[#a-heading]].

All types of links support completion, hover, goto definition/references. Additionally, Marksman provides diagnostics for wiki-links to detect broken references and duplicate/ambiguous headings.

Existing editor integrations3:

  • VSCode via Marksman VSCode.

  • Neovim:

  • Vim:

    • via ale - will support Marksman out-of-the-box once PR is merged; in the meantime...

      Example config (add the following to your ~/.vim/after/ftplugin/markdown.vim):

      if exists('g:loaded_ale')
        call ale#linter#Define('markdown', { 'name': 'marksman', 'lsp': 'stdio', 'executable': 'marksman', 'command': '%e server', 'initialization_options': {} })
      end
    • via lsp

      Example config (add the following to your ~/.vim/after/ftplugin/markdown.vim):

      if exists('g:loaded_lsp')
        call LspAddServer([#{ name: 'marksman', filetype: ['markdown'], path: '/path/to/marksman', args: ['server'], syncInit: v:true }])
      end
  • Emacs:

    • via LSP Mode (automatic server installation).

      Example config for use-package users:

      (use-package markdown-mode
        :hook (markdown-mode . lsp)
        :config
        (require 'lsp-marksman))
    • via Eglot, requires configuration (unless eglot#1013 gets merged); add the following to your init.el

      (add-to-list 'eglot-server-programs '(markdown-mode . ("marksman")))
      (add-hook 'markdown-mode-hook #'eglot-ensure)
  • Helix supports Marksman out of the box. However, you need add marksman binary to your PATH manually.

  • Sublime Text via LSP-marksman (automatic server installation).

  • BBEdit can be configured to use Marksman as an LSP server for Markdown files.

How to install

See the installation instructions.

Demos and tutorials

Completion Markdown

Features

See the Features page to learn more about language features, configurations, and single- and multi-file modes.

FAQ

  • Cross-file references and completions don't work.
    • Either create an empty .marksman.toml in the root folder of your project or initialize a repository (e.g. git init). See this page to learn more about single- and mult-file modes.
  • I'm getting "marksman can’t be opened because Apple cannot check it for malicious software" on MacOS.
    • Run the following command to bypass it and let Mac know that it's fine: xattr -d com.apple.quarantine <path-to-marksman-bin>.

Footnotes

  1. You may have heard about Roam Research. That is a commercial implementation of the Zettelkasten method and another point of reference for what Marksman is about. However, unlike a proprietary Roam Research, Marksman is free, open-source and integrated into your favourite editor (albeit for not not as feature rich as Roam Research).

  2. There is an excellent VSCode extension called Markdown Memo. You definitely need to check it out if you're primarily using VSCode as it has some features that are missing in Marksman and Marksman VSCode extension. However, Markdown Memo is VSCode specific while Marksman is a generic language server, so can be used with any editor that has LSP support: Emacs, Vim, Neovim, etc.

  3. Since Marksman is a regular Language Server most of the functionality works out of the box with any LSP client.

marksman's People

Contributors

artempyanykh avatar ckipp01 avatar eguiraud avatar franciscoj avatar goyalyashpal avatar joske avatar jparoz avatar kareigu avatar keynmol avatar majjoha avatar mrene avatar ngraham20 avatar pacien avatar pbnj avatar pedrolucasp avatar piero-vic avatar robwalt avatar rominf avatar scientificprogrammer avatar shawnfunke avatar shunsambongi avatar theblob42 avatar weakish avatar znd4 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

marksman's Issues

Generate TOC improvements

Now that #17 is merged, here's how it can be improved:

  1. If the document has a *single level-1 heading (=title), the TOC should be inserted right under it

    This means that the entire TOC will have to be shifted one level down (heading 2 becomes heading 3, etc.) and the original heading-1 is not rendered at all

  2. If the document has a YAML frontmatter, the TOC should be inserted under it (unless rule 1 applies)

    This would require to

    • Enable YAML parsing on Markdig
    • Propagate the location of yaml block all the way to Document Index

Add indentation configuration

Ideally, marksman should follow the indentation config of the editor (or currently open file or .editorconfig), however, when that does not work, users should be able to configure indentation via, e.g., indent property which could be either tab string or a number (how many spaces should be used for indentation).

Now, I have configured indentation to three spaces in Markdown files, however, the generated TOC looks like this: Actually, this was my mistake, as I actually used heading levels 1, 3, 4, and 3 instead of 1, 2, 3, 2).

example of my mistake
<!--toc:start-->
- [Heading 1]()
      - [Heading 2]()  <!-- 6 spaces -->
        - [Heading 3]()  <!-- 8 spaces -->
      - [Heading 2]()  <!-- 6 spaces -->
<!--toc:end-->

I would expect it to be as follows:

<!--toc:start-->
- [Heading 1]()
   - [Heading 2]()  <!-- 3 spaces -->
      - [Heading 3]()  <!-- 6 spaces -->
   - [Heading 2]()  <!-- 3 spaces -->
<!--toc:end-->

marksman always uses two spaces for indentation. The relevant line from Marksman/Toc.fs:

let offset = String.replicate (entry.level - minLevel) " "

Nix Support

I would like to use marksman on my nix based system, but I don't have any experience with packaging so far and failed when I tried to do so for marksman.

I'll assist as good as I can if someone else wants to try it out.

link completion gives LSP error

I have tried getting this to work and I think I am almost succeeded. Unfortunately when I try to auto complete a link to another file, then I get the following error:

image

After this point nothing works. I use the linux binary from the latest release and use it from within neovim.

The actual link is shown in the autocomplete box as it is expected to. I select it and press enter.

Root directory not found

Hello, so I am currently using WSL 2 Ubuntu, and I am having this error as shown in the pic when I run LspInfo on Neovim. I downloaded the latest release via curl, renamed the binary and even placed it inside my PATH folder. But for some reason, it seems like LSP is not properly detecting Marksman as completion and other features not seem to work. Here's the error message below with some additional images as reference:

image

In my bin folder:
image

In my .bashrc file:
image

Add completion for emojis

It might be a good idea to add an action/snippet to insert emojis, just like we do on GitLab and GitHub using a colon (e.g. :wink: → 😉).

Issue with subsection completion

I'm trying your LSP server in nvim 0.5, and I must admit I really like it.
It globally work fine, but there is an issue about completion. I don't really know if it's a server issue or client issue. (but I don't have this issue with other lsp servers, so I'm wondering)

The issue is when I try to complete a subsection, the completion provide the correct list of possible choices, but when I select a choice it only selects mi the "##" part of the title and not the text. If I type the title by hand the reference works fine, but this really reduces the workflow speed.

Take a look at the action :
zeta-bug

Add "single file mode"

Currently, Marksman requires a project/root/folder to provide language features such as cross-file references, workspace symbols, and rename refactor that works across many files.

However, it would be convenient to provide a subset of language features in situations where there's no project/root/folder. Some features like "document symbols" will be the same as before in "single-file mode". Other will lose cross-file capabilities and will work only intra-file, e.g. goto def, references, renames, completion. But perhaps this is enough for one-off edits of random markdown files.

Use filename instead of the title when auto-completing wiki-links

Hello, thank you for creating this project, it looks really useful!

My usecase is that I have a Zettelkasten repository containing a lot of interlinked notes with generated filenames. For example, my typical note might have a filename 202208240944.md and a content like this:

# Some title here

Lorem ipsum

If I try to link to this note from another file, I can type [[some and I will correctly get a list of suggestions with this note on the top. However, if I decide to use that suggestion, the result will become [[some-title-here]] instead of [[202208240944]]. In other words, marksman seems to assume that the title directly translates to the filename - but I think that is often not the case.

I've tried to use it with Kakoune (using kak-lsp) and Helix and both editors show the same behavior.

Move diagnostic calculation outside of the critical section

Right now, diagnostic calculation is added as a hook and happens inside a critical section: https://github.com/artempyanykh/marksman/blob/main/Marksman/Server.fs#L216; only the actual public of the updated diagnostic happens asynchronously. This means that diagnostic recalculation happens on every keystroke/state_update which is not cool and can lead to timeouts (albeit only on really huge workspaces with hundreds or thousands of md files).

The good news that it should be pretty easy to move diag recalc off of the critical section and make it happen async.

Autocomplete link markdown format

Is it possible to to configure autocompletion to insert markdown link format [Foo Bar](foo-bar.md) instead of wiki format [[foo-bar]]?

Helix editor causes Marksman to get stuck

as Title , lsp take error when change file .

2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "Unhandled exception: System.AggregateException: One or more errors occurred. (MailboxProcessor.PostAndAsyncReply timeout。)\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- " ---> System.TimeoutException: MailboxProcessor.PostAndAsyncReply timeout。\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at <StartupCode$FSharp-Core>[email protected](FSharpOption`1 res) in D:\\a\\_work\\1\\s\\src\\FSharp.Core\\mailbox.fs:line 472\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvokeNoHijackCheck[a,b](AsyncActivation`1 ctxt, b result1, FSharpFunc`2 userCode) in D:\\a\\_work\\1\\s\\src\\FSharp.Core\\async.fs:line 525\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in D:\\a\\_work\\1\\s\\src\\FSharp.Core\\async.fs:line 112\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   --- End of inner exception stack trace ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at Ionide.LanguageServerProtocol.Server.startWithSetup[client](FSharpFunc`2 setupRequestHandlings, Stream input, Stream output, FSharpFunc`2 clientCreator) in /Users/runner/work/marksman/marksman/LanguageServerProtocol/LanguageServerProtocol.fs:line 170\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at Marksman.Program.startLSP(Int32 verbosity, Boolean waitForDebugger) in /Users/runner/work/marksman/marksman/Marksman/Program.fs:line 58\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at [email protected](Tuple`2 tupledArg)\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at FSharp.SystemCommandLine.CommandBuilders.SetHandlerInt@207-2.Invoke(InvocationContext ctx)\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Invocation.AnonymousCommandHandler.Invoke(InvocationContext )\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<<UseParseErrorReporting>b__0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<<UseHelp>b__0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseVersionOption>b__0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass19_0.<<UseTypoCorrections>b__0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__18_0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseParseDirective>b__0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__5_0>d.MoveNext()\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "--- End of stack trace from previous location ---\n"
2022-08-18T19:34:09.381 helix_lsp::transport [ERROR] err <- "   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<<UseExceptionHandler>b__0>d.MoveNext()\n"
2022-08-18T19:34:09.394 helix_lsp::transport [ERROR] err: <- StreamClosed
2022-08-18T19:34:09.394 helix_lsp::transport [ERROR] err: <- StreamClosed
2022-08-18T19:34:11.320 helix_lsp::transport [ERROR] err: <- IO(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" })
2022-08-18T19:34:11.320 helix_lsp::transport [ERROR] err: <- IO(Os { code: 32, kind: BrokenPipe, message: "Broken pipe" })
2022-08-18T19:34:11.882 helix_lsp::transport [ERROR] err <- "[19:34:11 INF] <LSP Entry> Starting Marksman LSP server: {}\n"

os: macos 12.5
termial: alacritty
editor: helix
marksman: 1.0.0

lsp config: ~/.config/helix/languages.toml

[[language]]
name = "markdown"
indent = { tab-width = 4, unit = "    " }
file-types = ["md", "markdown"]
roots = [".git"]
language-server = { command = "marksman", args=["server"], language-id = "markdown" }

hx -vvv take log ~/.cache/helix/helix.log

Unable to get working on helix

I've tried configuring marksman as per the README but it doesn't work for me.

❯ hx --health markdown
Configured language server: marksman
Binary for language server: /home/zim/.local/bin/marksman
Configured debug adapter: None
Highlight queries: ✓
Textobject queries: ✘
Indent queries: ✘

I have an empty .marksman.toml file in the cwd.
log(hx -vvv file)->:log-open:

2022-09-17T12:17:52.443 helix_loader [DEBUG] Located configuration folders: []
2022-09-17T12:17:52.454 helix_view::clipboard [INFO] Using xclip to interact with the system and selection (primary) clipboard
2022-09-17T12:17:52.499 mio::poll [TRACE] registering event source with poller: token=Token(1), interests=READABLE | WRITABLE
2022-09-17T12:17:52.499 mio::poll [TRACE] registering event source with poller: token=Token(2), interests=READABLE | WRITABLE
2022-09-17T12:17:52.499 mio::poll [TRACE] registering event source with poller: token=Token(3), interests=READABLE | WRITABLE
2022-09-17T12:17:52.499 mio::poll [TRACE] registering event source with poller: token=Token(4), interests=READABLE | WRITABLE
2022-09-17T12:17:52.499 mio::poll [TRACE] registering event source with poller: token=Token(5), interests=READABLE | WRITABLE
2022-09-17T12:17:52.499 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}}},"completion":{"completionItem":{"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"snippetSupport":false},"completionItemKind":{}},"hover":{"contentFormat":["markdown"]},"publishDiagnostics":{},"rename":{"dynamicRegistration":false,"honorsChangeAnnotations":false,"prepareSupport":false},"signatureHelp":{"signatureInformation":{"activeParameterSupport":true,"documentationFormat":["markdown"],"parameterInformation":{"labelOffsetSupport":true}}}},"window":{"workDoneProgress":true},"workspace":{"applyEdit":true,"configuration":true,"didChangeConfiguration":{"dynamicRegistration":false},"symbol":{"dynamicRegistration":false},"workspaceFolders":true}},"processId":693130,"rootPath":"/home/zim/.md","rootUri":"file:///home/zim/.md","workspaceFolders":[{"name":".md","uri":"file:///home/zim/.md"}]},"id":0}
2022-09-17T12:17:52.499 mio::poll [TRACE] registering event source with poller: token=Token(0), interests=READABLE
2022-09-17T12:17:52.499 mio::poll [TRACE] registering event source with poller: token=Token(1), interests=READABLE
2022-09-17T12:17:53.070 helix_lsp::transport [ERROR] err <- "[12:17:52 INF] <LSP Entry> Starting Marksman LSP server: {}\n"
2022-09-17T12:17:54.275 helix_lsp::transport [INFO] <- {"jsonrpc":"2.0","id":0,"result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":2},"hoverProvider":true,"completionProvider":{"triggerCharacters":["[","#","("]},"definitionProvider":true,"referencesProvider":true,"documentSymbolProvider":true,"workspaceSymbolProvider":true,"codeActionProvider":{"resolveProvider":false},"renameProvider":true,"semanticTokensProvider":{"legend":{"tokenTypes":["property","variable"],"tokenModifiers":[]},"range":true,"full":{"delta":false}},"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":true},"fileOperations":{"didCreate":{"filters":[{"pattern":{"glob":"**/*.md","matches":"file","options":{"ignoreCase":true}}}]},"didDelete":{"filters":[{"pattern":{"glob":"**/*.md","matches":"file","options":{"ignoreCase":true}}}]}}}}}}
2022-09-17T12:17:54.275 helix_lsp::transport [INFO] <- {"capabilities":{"codeActionProvider":{"resolveProvider":false},"completionProvider":{"triggerCharacters":["[","#","("]},"definitionProvider":true,"documentSymbolProvider":true,"hoverProvider":true,"referencesProvider":true,"renameProvider":true,"semanticTokensProvider":{"full":{"delta":false},"legend":{"tokenModifiers":[],"tokenTypes":["property","variable"]},"range":true},"textDocumentSync":{"change":2,"openClose":true},"workspace":{"fileOperations":{"didCreate":{"filters":[{"pattern":{"glob":"**/*.md","matches":"file","options":{"ignoreCase":true}}}]},"didDelete":{"filters":[{"pattern":{"glob":"**/*.md","matches":"file","options":{"ignoreCase":true}}}]}},"workspaceFolders":{"changeNotifications":true,"supported":true}},"workspaceSymbolProvider":true}}
2022-09-17T12:17:54.275 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"initialized","params":{}}
2022-09-17T12:17:54.276 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"markdown","text":"# Zim's Setup Guide\n\n## Backups\n\n*   Browser plugins\n*   `~/.config` dir, rcs, scripts, etc.\n*   Could even use `rsync` to take backups\n\n## Installing Arch Linux\n\n[Arch Installation Guide](https://wiki.archlinux.org/title/installation_guide)\n\n### Prerequisite Knowledge:\n\n*   Selecting mirrors with [ reflector ](https://wiki.archlinux.org/title/Reflector)\n\n*   Chrooting: In case something goes wrong with your installation you will have to chroot into your installation for which you will have to first mount your \"root\" partition and **then** the \"EFI system\" partition. Althought sometimes you might not need to mount the \"EFI system\" partition. We made the installation at `/root` and our EFI mount point(according to the installation guide) is at `/boot`\n\n*   Install gvim/nvim during `pacstrap`\n\n*   To install other packages or package groups, append the names to the pacstrap command above (space separated) or use pacman while [ chrooted ](https://wiki.archlinux.org/title/installation_guide#Chroot) into the new system.\n\n*   Necessary packages:\n    ```console\n    pacman -Sy xorg alsa network-manager-applet polybar haskell-random acpi brightnessctl zellij fish nushell kitty alacritty rofi feh xorg-xinit starship man-db man-pages slock\n    ```\n\n*   Rust installation(for paru): `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`\n    ```console\n    sudo pacman -S --needed base-devel\n    git clone https://aur.archlinux.org/paru.git\n    cd paru\n    makepkg -si\n\n    paru -Sy otf-font-awesome-5 xmonad-git xmonad-contrib-git brave-bin microsoft-edge-stable-bin kmonad-git\n    ```\n\n### Installing Bootloader\n\nIn the installation guide our boot partition was mounted at `/mnt/boot` and `/boot` while chrooted. Let's install Gummiboot now:\n\n*   Install using: `bootctl install` which might result in an error, usually complaining about the efi dir not found.\n*   [Configure gummiboot](https://wiki.archlinux.org/title/Systemd-boot#Configuration). Also, checkout [github gists](https://gist.github.com/zim0369) for \"arch.conf\" and \"loader.conf\"\n\n## Setting up the System\n\n### Necessary Knowledge\n\n[System Maintenance](https://wiki.archlinux.org/title/system_maintenance)\n\n[General Recommendations](https://wiki.archlinux.org/title/General_recommendations)\n\n### Placing Required Files\n","uri":"file:///home/zim/.md/arch_install.md","version":0}}}

Add an installation guide

Please add a guide to README.md on how to install, place binaries in the system or compile from source.

Don't include `source` code action by default

Marksman returns code action of the source kind (titled Create a Table of Contents) when editor asks for code actions without explicitly specifying any kinds.

For example editor make this request:

{
  "context": {
    "diagnostics": [],
    "triggerKind": 2
  },
  "range": {
    "end": {
      "character": 0,
      "line": 0
    },
    "start": {
      "character": 0,
      "line": 0
    }
  },
  "textDocument": {
    "uri": "file:///usr/local/workspace/sublime-packages/LSP/README.md"
  }
}

and marksman returns:

[
  {
    "edit": {
      "changes": {
        "file:///usr/local/workspace/sublime-packages/LSP/README.md": [
          {
            "newText": "<!--toc:start-->\n- [Installation](#installation)\n  - [Stable Version](#stable-version)\n  - [Development Version](#development-version)\n- [Getting started](#getting-started)\n- [Getting help](#getting-help)\n<!--toc:end-->\n\n",
            "range": {
              "end": {
                "character": 0,
                "line": 0
              },
              "start": {
                "character": 0,
                "line": 0
              }
            }
          }
        ]
      }
    },
    "isPreferred": false,
    "kind": "source",
    "title": "Create a Table of Contents"
  }
]

I don't have any explicit description of expected behavior for this but based on VSCode primarily (and what we have mirrored in Sublime Text) it seems that the source code actions should not be returned unless specifically asked for by the editor. Not following this logic results in editor providing source diagnostics for every location in the file (since editors request diagnostics for the current selection/cursor position) which is non-ideal for those kind of code actions.

(This issue originated from the discussion in sublimelsp/LSP#1846 (comment))

Table Formatting

Formatting tables manually is a pain. Does table formatting sound like a plausible feature? I can use a third party formatter in the meantime but it does sound convenient.

YAML front matter support

Looking at my hakyll blog posts (e.g. this) I see the following structure

---
title: [title]
...
---

## Heading 1
## Heading 2

Since there's no 1st level heading there's no clash between yaml's title and a potential markdown # Title.

I guess the question for me is: in the presence of a front matter do we want to
a) treat front matter's title as a level 1 heading and therefore prohibit the use of # ... in the body of the document.

---
title: Front matter
---

# I am prohibited <-- this will be flagged as a duplicate title

## Why

## When

b) treat front matter's title as a level 0 heading and level 1 headings will be just regular document headings and there can be multiple of those, e.g.

---
title: Front matter
---

# What is front matter <-- OK

# Why front matter <-- Also OK

How to enable/configure single-file mode?

The README says the following, but how to enable?

Marksman has a custom single-file mode that provides a subset of language features for markdown files open outside of any project. This works well for small one-off edits or when opening random markdown files.

Reference link labels should be case-insensitive

First, marksman treat link labels case sensitive.
For exmaple, the following markdown triggers a false positive warning.

[A][]

[a]: https://example.com

According to John Gruber's canonical description of Markdown's syntax,
link labels are case insensitive.

Link definition names may consist of letters, numbers, spaces, and punctuation — but they are not case sensitive. E.g. these two links:

[link text][a]
[link text][A]

are equivalent.

Second, marksman does not recognize shortcut reference links.
For example, the following markdown does not trigger any warnings.

[b]

Shortcut reference links were introduced by Gruber himself in a beta version of Markdown.pl, but never included in the official syntax description.
Most popular markdown parsers support shortcut referneces.
Also, CommonMark includes shortcut reference links in its specification.

; marksman --version
1.0.0-19de239

vscode-screenshot

`Async job failed: request timed out` when using `open workspace symbol picker` in Helix

I have a directory full of all sorts of random things, including markdown files. It has a .git repo initialized at the root.

If I cd into it and open a markdown file with headings, the space e - open symbol picker works like a charm with the headings!

Unfortunately if I choose space E - open workspace symbol picker then the language server hangs, and I get Async job failed, request timed out appearing randomly in red at the bottom of the screen. I need to restart Helix to get marksman working again.

LSP position back to offset

I have such a requirement, I need to know what AST node is currently selected by the mouse.

My AST uses offset to store range information.

Because binary search based on offset is easier to write.

The error reporting library (ariadne) I use is also offset based.

So I want an method like the following:

fn lsp_pos_to_offset(&self, lsp_pos: &lsp_types::Position) -> Option<usize>

Why not wiki-links?

Any reason for choosing [:another-note] over the more widely used [[another-note]] syntax? Maybe I'm missing the trade-offs behind this decision, but using wiki-links means your notebook works with a wide variety of editors and tools.

Incorrect link to header generated when header contain link.

Hi,
thanks for great LSP server. I noticed that when I use link in header like in the example bellow the server autocompletes incorrect link like in the example:

# Google

test

# [Google link](https://google.com)

test

[google link](#google)
[google link with link](#google-linkhttpsgooglecom)

I believe the second link should omit the url part like this#google-link.

Here is screenshot from neovim how I see autocomplete options for this example:

incorrect-link-screenshot

Support rename refactoring

E.g.

Here comes the [foo]!

[foo]: url

We should be able to rename [foo] and all its occurrences in the document.

Same goes for headings:

# Doc 1
# Doc 12
[[doc-1]]
[[doc-1#doc-12]

Should be able to rename title and headings and update all references.

Config flags to enable/disable diagnostics

There are many extensions to markdown that define there own flavors of links. Lack of support for these extensions may trigger diagnostics that can be distracting. The idea is to provide an option to disable various types of diagnostics while still be able to use other pieces of functionality from the supported set.

Implement incremental update of a line map

Currently, we calculate line map from scratch after every update. With incremental text sync we could do better than this.

The idea is to implement an incremental recalculation of a line map, e.g.

val incrementalUpdate : initMap:LineMap -> changedRange:Range -> changeMap:LineMap -> LineMap

Does marksman support lint?

Hi, thanks for the great lang server for markdown.
I am wondering if marksman support markdownlint or other lint tools/plugins?

[Bug] marksman is missing LSP server capabilities in Neovim

It seems that some LSP server capabilities such as diagnostic, find references etc. are missing when using marksman with Neovim:

image

My Neovim config:

local M = {}

M.config = function()
  local lsp_configs = require "lspconfig.configs"

  local cmd
  cmd = { "marksman", "server" }

  lsp_configs.marksman = {
    default_config = {
      cmd = cmd,
      filetypes = { "markdown" },
      root_dir = function(fname)
        local util = require "lspconfig.util"
        local root_files = {
          ".marksman.toml",
        }
        return util.root_pattern(unpack(root_files))(fname) or util.root_pattern ".git"(fname) or util.path.dirname(fname)
      end,
      settings = {},
    },
  }

  local status_ok, lsp = pcall(require, "lspconfig")
  if not status_ok then
    return
  end

  if lsp.marksman.setup then
    lsp.marksman.setup {
      on_attach = function(client, bufnr)
      end,
      on_init = require("lvim.lsp").common_on_init,
      capabilities = require("lvim.lsp").common_capabilities(),
    }
  end
end
return M

I created an empty .marksman.toml file at the root of my notebooks path.

Server never initializes if no workspaceFolders are given

The server never responds to the initialize request from the client, if it contains workspaceFolders: null.

From the LSP specs:

        /**
	 * The workspace folders configured in the client when the server starts.
	 * This property is only available if the client supports workspace folders.
	 * It can be `null` if the client supports workspace folders but none are
	 * configured.
	 *
	 * @since 3.6.0
	 */
	workspaceFolders?: [WorkspaceFolder](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspaceFolder)[] | null;

Support relative paths in markdown inline links

Currently, marksman supports go-to definition for inline links with absolute paths only (absolute relative to the repo/folder root), e.g.

[title](/path-to-file.md)

We should also support relative paths (at least in terms of go-to definition/references) e.g.

[title](./path-to-file.md)

Neovim support

Since 0.5 release neovim supports lsp. So, there is a project lsp-config where your lsp server is added as supported.

But when I try to integrate it in my workflow I always got errors. Authors of that plugin advice me to wright to you about issues. So my questions are:

  1. May I open any issues about integration your lsp- server in nvim or your work is just around vsCode?
  2. May you try to integrate zeta-note to nvim and wright a little tutorial if it works fine for you?

Thx for your work!)

Duplicate headers error

In a document like:

# Changelog

## [14.0]
### Breaking
- foo

## [13.0]
### Breaking
- bar

The second Breaking header is reported as duplicate. I think it doesn't make sense since it's under different parent header.

Document Symbols Ordering

I have a file like so:

# Heading 1

## Subheading 1.1

## Subheading 1.2

# Heading 2 

## Subheading 2.1

## Subheading 2.2

When I open the symbol picker I expect the ordering to be top to bottom, but it instead lists H1s first, then H2s:

sym_picker

Support ignore files

The idea is to look for:

  1. either .gitignore
  2. or just .ignore
    at the root of the project and use the globs there to exclude dirs/files from scanning.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.