GithubHelp home page GithubHelp logo

mrjones2014 / dash.nvim Goto Github PK

View Code? Open in Web Editor NEW
234.0 5.0 16.0 189.47 MB

๐Ÿƒ๐Ÿ’จ Search Dash.app from your Neovim fuzzy finder. Built with Rust ๐Ÿฆ€ and Lua

License: Mozilla Public License 2.0

Lua 19.72% Makefile 2.35% Shell 4.06% Rust 72.17% Vim Script 1.69%
neovim neovim-plugin lua neovim-lua dash documentation telescope nvim-telescope nvim nvim-plugin

dash.nvim's Introduction


Dash.nvim is looking for a maintainer!

I don't use this plugin anymore and don't have time to maintain it. If you are interested in maintaining this repo, please open an issue or discussion!


Build Rust Lua

Dash.nvim

Query Dash.app within Neovim with your fuzzy finder!

demo

The theme used in the recording is lighthaus.nvim.

Note: Dash is a Mac-only app, so you'll only find this plugin useful on Mac.

Install

This plugin must be loaded after your fuzzy finder plugin of choice. Currently supported fuzzy finder plugins are:

After installing Dash.nvim, you must run make install. This can be done through a post-install hook with most plugin managers.

Packer:

use({
  'mrjones2014/dash.nvim',
  run = 'make install',
})

Paq:

require("paq")({
  { 'mrjones2014/dash.nvim', run = 'make install' };
})

Vim-Plug:

Plug 'mrjones2014/dash.nvim', { 'do': 'make install' }

Build From Source

If you prefer not to trust the binaries hosted in the repository, you can build from source. This requires installing the latest stable Rust toolchain from rustup.rs. Once you have the Rust toolchain set up, you can clone this repository, and run make build-local install. make build-local will auto-detect the host machine's architecture and build for that target, and make install will copy the binaries into you Lua runtime path. Once you've done this, you can install into Neovim by pointing your plugin manager to the local repository path on disk instead of mrjones2014/dash.nvim.

Usage

Run :h dash to see these docs in Neovim.

Editor Commands

This plugin has two editor commands, :Dash and :DashWord, each of which accept a bang (!). By default, it will search Dash.app with keywords based on config (see file_type_keywords in configuration). The bang (!) will search without this keyword filtering.

:Dash [query] will open the fuzzy finder, and if [query] is passed, it will pre-fill the prompt with [query]. This is essentially an alias to :lua require('dash').search(bang, [query]).

:DashWord will open the fuzzy finder and pre-fill the prompt with the word under the cursor. This is essentially an alias to :lua require('dash').search(bang, <cword>).

The Lua function require('dash').search() will bind to the first supported fuzzy finder plugin it detects. Having multiple fuzzy finder plugins installed will result in undefined behavior. You can use a specific fuzzy finder's provider directly via :lua require('dash.providers.telescope').dash({ bang = false, initial_text = '' }), for example.

If using Telescope, you can also run :Telescope dash search or :Telescope dash search_no_filter.

If using fzf-lua, you can also run :FzfLua dash or :lua require('fzf-lua').dash({ bang = false, initial_text = '' }).

If using Snap, you can also run :lua require('dash.providers.snap').dash({ bang = false, initial_text = '' }).

Configuration

Configuration Table Structure

{
  -- configure path to Dash.app if installed somewhere other than /Applications/Dash.app
  dash_app_path = '/Applications/Dash.app',
  -- search engine to fall back to when Dash has no results, must be one of: 'ddg', 'duckduckgo', 'startpage', 'google'
  search_engine = 'ddg',
  -- debounce while typing, in milliseconds
  debounce = 0,
  -- map filetype strings to the keywords you've configured for docsets in Dash
  -- setting to false will disable filtering by filetype for that filetype
  -- filetypes not included in this table will not filter the query by filetype
  -- check src/lua_bindings/dash_config_binding.rs to see all defaults
  -- the values you pass for file_type_keywords are merged with the defaults
  -- to disable filtering for all filetypes,
  -- set file_type_keywords = false
  file_type_keywords = {
    dashboard = false,
    NvimTree = false,
    TelescopePrompt = false,
    terminal = false,
    packer = false,
    fzf = false,
    -- a table of strings will search on multiple keywords
    javascript = { 'javascript', 'nodejs' },
    typescript = { 'typescript', 'javascript', 'nodejs' },
    typescriptreact = { 'typescript', 'javascript', 'react' },
    javascriptreact = { 'javascript', 'react' },
    -- you can also do a string, for example,
    -- sh = 'bash'
  },
}

If you notice an issue with the default config or would like a new file type added, please file an issue or submit a PR!

With Telescope

require('telescope').setup({
  extensions = {
    dash = {
      -- your config here
    }
  }
})

With fzf-lua or Snap

require('dash').setup({
  -- your config here
})

Lua API

The public API consists of two main functions.

-- See src/lua_bindings/dash_config_binding.rs for available config keys
-- Also described in configuration section below
---@param config
require('dash').setup(config)
--- This will bind to the first fuzzy finder it finds to be available,
--- checked in order: telescope, fzf-lua
---@param bang boolean @bang searches without any filtering
---@param initial_text string @pre-fill text into the finder prompt
require('dash').search(bang, initial_text)

See backend for documentation on the backend data provider.

Backend

To build from source, you will need a Rust toolchain, which can be installed from rustup.rs. Once this is installed, you should be able to build via make build. Then, make install will copy the correct binary into the lua/ directory so that it is added to Lua's runtimepath.

The Rust backend is exposed as a Lua module. To require the module, you will need to have the file libdash_nvim.so for your architecture (M1 or Intel) on your runtimepath, as well as the deps directory, which must be in the same directory as the libdash_nvim.so shared library file.

Constants

The Rust backend exports the following constants for use:

  • require('libdash_nvim').DASH_APP_BASE_PATH => "/Applications/Dash.app"
  • require('libdash_nvim).DASH_APP_CLI_PATH => "/Contents/Resources/dashAlfredWorkflow"

libdash_nvim.config (table)

This table stores the internal configuration. You can access it via require('libdash_nvim').config. See src/lua_bindings/dash_config_binding.rs or configuration above for configuration keys.

libdash_nvim.default_config (table)

This table stores the default configuration. You should not modify this table, treat it as read-only. This is mainly to help with merging your custom config with the default config, but can be useful for debugging purposes. For example:

:lua print(vim.inspect(require('libdash_nvim').default_config))

libdash_nvim.setup (function)

This method is used to set the internal configuration of the backend. It takes a table, which will be merged with the default configuration. See src/lua_bindings/dash_config_binding.rs or configuration above for configuration keys.

require('libdash_nvim').setup({
  -- your custom configuration here
})

libdash_nvim.query (function)

This method takes a table as its argument. The table should have the following keys:

  • search_text - the search text entered by the user
  • buffer_type - the current buffer type, this will be used to determine filter keywords from config
  • ignore_keywords - disables filtering by keywords if true (e.g. if run with bang, :Dash! or :DashWord!)
local libdash = require('libdash_nvim')
local results = libdash.query({
  search_text = 'match arms',
  buffer_type = 'rust',
  ignore_keywords = false
})

The query method returns a table list of tables (a Rust Vec<DashItem> serialized to a Lua table, see src/dash_item.rs) with the following properties:

  • value - the number value of the item, to be used when selected
  • ordinal - a value to sort by, currently this is the same value as display
  • display - a display value
  • keyword - the keyword (if there was one) on the query that returned this result
  • query - the full query that returned this result
  • is_fallback - indicates whether the item represents a search engine fallback and should be handled as such

If no items are returned from querying Dash, it will return a single item with an extra key, is_fallback = true. The table will look something like the following:

{
  value = 'https://duckduckgo.com/?q=rust match arms',
  ordinal = '1',
  display = 'Search with DuckDuckGo: rust match arms',
  keyword = 'rust',
  query = 'rust:match arms',
  is_fallback = true,
}

libdash_nvim.open_item (function)

Takes an item returned from querying Dash via the require('libdash_nvim').query function and opens it in Dash.

local libdash = require('libdash_nvim')
local results = libdash.query({
  search_text = 'match arms',
  buffer_type = 'rust',
  ignore_keywords = false
})
local selected = results[1]
require('libdash_nvim').open_item(selected)

libdash_nvim.open_url (function)

Simply takes a URL string and opens it in the default browser/handler for the URL protocol. This is used for both opening the search engine fallback via an HTTPS URL, as well as opening the selected DashItem in Dash.app via the dash-workflow-callback:// URL protocol.

require('libdash_nvim').open_url('https://duckduckgo.com/?q=array.prototype.filter')
require('libdash_nvim').open_url('dash-workflow-callback://5')

Contributing

Git Hooks

If you plan on changing Rust code, you will need to install the git hooks via make install-hooks. The git hooks require you have a Rust toolchain installed. You can install a Rust toolchain from rustup.rs.

Developing Locally

The best way to develop and test locally is to install the plugin from a locally cloned repository. If you're using Packer, you can just do:

use({
  '~/git/dash.nvim', -- or whatever your local path is
  run = 'make install',
})

Otherwise you can add it manually via:

vim.opt.runtimepath:append('~/git/dash.nvim') -- or whatever your local path is

There is also a make dev task which will set the $DASH_NVIM_DEV environment variable and open nvim for you. When the $DASH_NVIM_DEV environment variable is set, there will be an extra command available, :DashDevReload. This will reload Telescope, fzf-lua, and Snap (whichever ones you have installed), as well as the dash and libdash_nvim Lua modules.

To recompile the Rust backend for your machine's CPU architecture and install the module, run make build-local install. make build-local will auto-detect your machine's architecture and build for that target, and make install will copy the compiled binaries into your Lua runtime path.

Running Tests

You can run all tests (both Rust and Lua) with make test.

Lua Tests

This uses busted, luassert (both through plenary.nvim) and matcher_combinators to define tests in spec/ directory. These dependencies are required only to run tests, that's why they are installed as git submodules.

To run Lua tests, run make test-lua. This runs tests in Neovim with a minimal profile, spec.vim. This runs Neovim with only this plugin, and the testing dependencies.

If you have entr(1) installed, you can run the tests in watch mode using make watch.

Rust Tests

Rust tests use built-in Rust assertions and test modules. To run Rust tests, run make test-rust.

Code Style

Use snake_case for everything. All Lua code should be checked and formatted with luacheck and stylua. Only presentation-layer code (such as providers for various fuzzy finder plugins) should be in the Lua code, any core functionality most likely belongs in the Rust backend.

All Rust code should be checked and formatted using rust-analyzer, and linted using clippy, which can be run via make lint-rust.

dash.nvim's People

Contributors

knpwrs avatar mrjones2014 avatar xomute 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

dash.nvim's Issues

Error on startup in macOS: module 'libdash_nvim' not found

The plugin was working at earlier points but since recent updates it stopped working. On the latest master as of today (791281f) and NVIM v0.6.0-dev+1984-g09e96fe60:

Error detected while processing $HOME/.dotfiles/vim/plugged/dash.nvim/plugin/dash.vim:
line   16:
E5108: Error executing lua 
$HOME/.vim/plugged/dash.nvim/lua/dash/config.lua:6: module 'libdash_nvim' not found:
        no field package.preload['libdash_nvim']
        no file './libdash_nvim.lua'
        no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/share/luajit-2.1.0-beta3/libdash_nvim.lua'
        no file '/usr/local/share/lua/5.1/libdash_nvim.lua'
        no file '/usr/local/share/lua/5.1/libdash_nvim/init.lua'
        no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/share/lua/5.1/libdash_nvim.lua'
        no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/share/lua/5.1/libdash_nvim/init.lua'
        no file './libdash_nvim.so'
        no file '/usr/local/lib/lua/5.1/libdash_nvim.so'
        no file '/usr/local/Cellar/luajit-openresty/2.1-20210510/lib/lua/5.1/libdash_nvim.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'

Environments: Mac OS 11.6, x86_64 (Intel)

This is because the prebuilt binary is only provided as *.so shared module; macOS would require *.dylib.

I think recent changes on the bin/ structure broke the plugin. (commit dfd928c, since v0.4.0)

Experiment with exposing a Lua API directly from the Rust backend

There's a few different crates to support Lua bindings in Rust

We should experiment with writing a Lua API directly embedded into the Rust backend. This will likely be a lot faster than running it via the CLI with plenary.

Basically, the Rust backend should expose a single function, require('dash-backend').query({ dash_app_path = "/Applications/Dash.app", query1, query2, ... }) and return a Lua table directly, instead of outputting JSON on the command line.

Remove `ftdetect` files

The only one in there currently is handlebars filetype detection. If someone is using Handlebars, chances are they're also using a plugin for it, and filetype detection shouldn't be a concern of this plugin.

Expand ~ in `dashAppPath` when calling `setup()`

When we call require('dash').setup({ dashAppPath = '~/Applications/Dash.app' }) we should expand the ~. Currently I don't think it gets expanded so you need to use os.getenv('HOME') instead of ~.

consolidate constants

we have 2 constants files. now that rust lua module is working we should only have 1

Packer - Failed to install - git timeout, and no post install hook

Installing with packer with use({ 'mrjones2014/dash.nvim', requires = { 'nvim-telescope/telescope.nvim' }, run = 'make install' }), I get a "Failed to install" when running a PackerSync. Thereafter, I get "module "libdash_nvim" not found, did you set up Dash.nvim with make install as a post-install hook?"

Debugging a bit, I found two things:

  1. Git times out frequently: ...m/site/pack/packer/start/packer.nvim/lua/packer/jobs.lua:87: Killing git due to timeout!. Now, the connection I'm on is a little weak, but it still downloaded from github at ~500kb/s. I worked around this for now by increasing timeout to 120s (from 60s). None of my other plugins needed this, though...
  2. Having worked around that, the post install hook doesn't seem to run? After the packer sync, I guess it tries to load the module, because the debug log shows "Vim(lua):module "libdash_nvim" not found, did you set up Dash.nvim with make install as a post-install hook? See :h dash-install". So maybe that failing is preventing the hook from executing?

I solved the problem for now by cding to the dash dir and running make install manually.

Feature Request: Dash <args>

Feature request: It would be good to have :Dash <query> (e.g., :Dash blah blah) for a command that launches the telescope window with <query> as a initial query (like :DashWord).

Move `lua/dash/query-builder.lua` to the Rust backend

Instead of passing the full list of queries to the backend, we should be able to just pass the current file type, the prompt, and whether it was triggered with the bang (!).

This might require moving the config itself into the Rust code as well, but I'm not sure if/how that will work.

Allow a way to do a one-off search without keywords

For example, in a typescript file, it will search with typescript keywords. But there should also be a way to do a search with no keywords. Possibly something like :Dash all or :Dash false or something. Not sure exactly how it should work.

Previews?

Is it possible to enable previews? Might only be possible in GUI vim since the docs are HTML documents.

convert to snake_case

It seems in the Lua world, pretty much everything uses snake_case. Let's migrate everything from being camelCase to snake_case.

Offload query building to the Rust backend

Right now the query building based on the buffer type happens in the telescope utils file. In order to support other fuzzy finders (see #25) we should offload that to the backend and make the Rust code responsible for building the query based on the filetype.

Most likely this requires putting the config module in the backend as well.

More intelligent `:DashWord` using LSP or TreeSitter

Original request from #26

my dream feature would be to use the LSP and/or Treesitter to lookup the docs for the method on the correct object type. In other words, var_that_is_a_tempfile.[o]pen (with the cursor on the o) would open the docs for specifically Tempfile.open.

I'm not sure how we'd implement this but I think it might be possible via LSP info or TreeSitter.

Fall back to google / stack overflow search, like Dash app?

In the case a search doesn't come up with anything, it would be nice if there would be a search the web fallback, like the Dash app has, so I don't have to go open my browser and type the same thing in again.

Awesome idea and execution by the way, this has sped me up so much, especially when working with a language I'm not too familiar with. Love it. Thank you ๐Ÿ™

Results sometimes wrongly return empty

I've got the React docset installed, and some searches work perfectly:

Screen Shot 2021-10-25 at 7 29 19 PM

But other searches return nothing:
Screen Shot 2021-10-25 at 7 29 46 PM

Compare the above to the Dash app results:

Screen Shot 2021-10-25 at 7 30 12 PM

I've looked briefly into how the query thing works and it looks like it calls "/Applications/Dash.app/Contents/Resources/dashAlfredWorkflow" with the query, I can confirm that it returns some results, here's what gets returned:

https://gist.github.com/marcusbuffett/b3490d47696c7240d3f77daa03aae245

Let me know if there's any debug info that could be useful.

FZF/fzf-lua support (or generic datasource provider for other pickers)

Love this! I imagine that since you don't use fzf-lua you'd likely not want to spend time adding support. I haven't dove deep into this repo yet, so forgive me if this already exists.. would you be willing to add some sort of provider so that other pickers might be used?

Thanks!

(PS. I'd be interested in adding fzf-lua support if you were up for having that added)

Feature Request: Docs for word under cursor

I'm coming from dash.vim, which has a feature to search for the word under the cursor. (Optionally?) Having the telescope window auto-populate with that word would be helpful.

However, I found that this didn't always work as well as one would like, because the method searched could sometimes belong to quite a few different types of classes. For example, open in Ruby, which in Dash gives results for 36 objects. So my dream feature would be to use the LSP and/or Treesitter to lookup the docs for the method on the correct object type. In other words, var_that_is_a_tempfile.[o]pen (with the cursor on the o) would open the docs for specifically Tempfile.open.

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.