├── .styluaignore ├── examples ├── javascript.js ├── python.py ├── lua-chat.gif ├── javascript.gif └── python-chat.gif ├── chat ├── icon.png ├── manifest.json ├── Cargo.toml ├── asset-manifest.json ├── src │ └── main.rs └── Cargo.lock ├── LICENSE.md ├── .editorconfig ├── .gitmodules ├── .luarc.json ├── .gitignore ├── stylua.toml ├── .github ├── CODEOWNERS ├── workflows │ ├── enforce-pr-jira-association.yml │ ├── lua-format-check-pr.yml │ └── chat.yaml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug-report.md ├── lua ├── tabnine │ ├── state.lua │ ├── consts.lua │ ├── features.lua │ ├── chat │ │ ├── setup.lua │ │ ├── user_commands.lua │ │ ├── auto_commands.lua │ │ ├── codelens.lua │ │ ├── binary.lua │ │ ├── apply.lua │ │ └── init.lua │ ├── config.lua │ ├── workspace.lua │ ├── keymaps.lua │ ├── auto_commands.lua │ ├── status.lua │ ├── user_commands.lua │ ├── lsp.lua │ ├── binary.lua │ ├── completion.lua │ └── utils.lua ├── lualine │ └── components │ │ └── tabnine.lua └── tabnine.lua ├── dl_binaries.ps1 ├── dl_binaries.sh ├── doc └── tabnine.txt └── README.md /.styluaignore: -------------------------------------------------------------------------------- 1 | lua/tabnine/third_party/ 2 | -------------------------------------------------------------------------------- /examples/javascript.js: -------------------------------------------------------------------------------- 1 | // calculate average of array 2 | 3 | -------------------------------------------------------------------------------- /examples/python.py: -------------------------------------------------------------------------------- 1 | # calculate average of array 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /chat/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codota/tabnine-nvim/HEAD/chat/icon.png -------------------------------------------------------------------------------- /examples/lua-chat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codota/tabnine-nvim/HEAD/examples/lua-chat.gif -------------------------------------------------------------------------------- /examples/javascript.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codota/tabnine-nvim/HEAD/examples/javascript.gif -------------------------------------------------------------------------------- /examples/python-chat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codota/tabnine-nvim/HEAD/examples/python-chat.gif -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | tabnine-nvim is offered under the [Tabnine Terms of Service](https://www.tabnine.com/terms). 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | [*] 3 | end_of_line = lf 4 | insert_final_newline = true 5 | charset = utf-8 6 | 7 | [*.lua] 8 | indent_style = tab 9 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lua/tabnine/third_party/semver"] 2 | path = lua/tabnine/third_party/semver 3 | url = https://github.com/kikito/semver.lua.git 4 | -------------------------------------------------------------------------------- /.luarc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/sumneko/vscode-lua/master/setting/schema.json", 3 | "Lua.diagnostics.globals": ["autocomplete"], 4 | "unusedLocalExclude": ["_*"] 5 | } 6 | -------------------------------------------------------------------------------- /chat/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Tabnine Chat", 3 | "name": "Tabnine Chat", 4 | "icons": [], 5 | "start_url": ".", 6 | "display": "standalone", 7 | "theme_color": "#000000", 8 | "background_color": "#ffffff" 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | binaries/* 2 | doc/tags 3 | 4 | **.DS_Store 5 | .disabled 6 | 7 | registration_key 8 | sig 9 | auth 10 | .idea/ 11 | *.iml 12 | 13 | 14 | # Added by cargo 15 | 16 | target/ 17 | 18 | chat_state.json 19 | chat_settings.json 20 | -------------------------------------------------------------------------------- /stylua.toml: -------------------------------------------------------------------------------- 1 | column_width = 120 2 | line_endings = "Unix" 3 | indent_type = "Tabs" 4 | quote_style = "AutoPreferDouble" 5 | call_parentheses = "Always" 6 | collapse_simple_statement = "ConditionalOnly" 7 | 8 | [sort_requires] 9 | enabled = true 10 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # The following github team will be considered code-owners for all account repositories 2 | # code-owners will be later applied as merge approvers for all pull requests in order to comply with our SOC2 Policy. 3 | * @codota/merge-approvers @amirbilu 4 | -------------------------------------------------------------------------------- /lua/tabnine/state.lua: -------------------------------------------------------------------------------- 1 | local uv = vim.uv or vim.loop 2 | 3 | return { 4 | requests_counter = 0, 5 | completions_cache = nil, 6 | rendered_completion = nil, 7 | cancel_completion = nil, 8 | debounce_timer = uv.new_timer(), 9 | debounce_ms = 0, 10 | active = nil, 11 | } 12 | -------------------------------------------------------------------------------- /lua/lualine/components/tabnine.lua: -------------------------------------------------------------------------------- 1 | local M = require("lualine.component"):extend() 2 | local status = require("tabnine.status") 3 | 4 | function M.init(self, options) 5 | M.super.init(self, options) 6 | end 7 | 8 | function M.update_status() 9 | return status.status() 10 | end 11 | 12 | return M 13 | -------------------------------------------------------------------------------- /chat/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tabnine_chat" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | image = "0.24.6" 10 | once_cell = "1.18.0" 11 | regex = "1.8.4" 12 | serde = { version = "1.0.164", features = ["derive"] } 13 | serde_json = "1.0.99" 14 | wry = "0.29.0" 15 | -------------------------------------------------------------------------------- /lua/tabnine/consts.lua: -------------------------------------------------------------------------------- 1 | local api = vim.api 2 | 3 | return { 4 | plugin_version = "1.7.0", 5 | min_nvim_version = "0.7.1", 6 | max_chars = 3000, 7 | tabnine_hl_group = "TabnineSuggestion", 8 | tabnine_codelens_hl_group = "TabnineCodeLens", 9 | tabnine_namespace = api.nvim_create_namespace("tabnine"), 10 | tabnine_codelens_namespace = api.nvim_create_namespace("tabnine_codelens"), 11 | valid_end_of_line_regex = vim.regex("^\\s*[)}\\]\"'`]*\\s*[:{;,]*\\s*$"), 12 | } 13 | -------------------------------------------------------------------------------- /lua/tabnine/features.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local tabnine_binary = require("tabnine.binary") 3 | 4 | function M.if_feature_enabled(features, run_if_enabled) 5 | tabnine_binary:request({ Features = { dummy = true } }, function(response) 6 | if not response or not response.enabled_features then return end 7 | for _, feature in ipairs(features) do 8 | if vim.tbl_contains(response.enabled_features, feature) then 9 | run_if_enabled() 10 | return 11 | end 12 | end 13 | end) 14 | end 15 | 16 | return M 17 | -------------------------------------------------------------------------------- /.github/workflows/enforce-pr-jira-association.yml: -------------------------------------------------------------------------------- 1 | name: Enforce PR-Jira association 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - reopened 8 | - edited 9 | - synchronize 10 | 11 | jobs: 12 | enforce-issue: 13 | runs-on: ubuntu-latest 14 | name: JIRA Association 15 | steps: 16 | - name: Check for JIRA ISSUE 17 | id: check 18 | uses: usehaystack/jira-pr-link-action@v4 19 | with: 20 | ignore-author: dependabot[bot] 21 | project: "DEV2" 22 | -------------------------------------------------------------------------------- /lua/tabnine/chat/setup.lua: -------------------------------------------------------------------------------- 1 | local auto_commands = require("tabnine.chat.auto_commands") 2 | local chat = require("tabnine.chat") 3 | local config = require("tabnine.config") 4 | local features = require("tabnine.features") 5 | local user_commands = require("tabnine.chat.user_commands") 6 | 7 | local M = {} 8 | 9 | function M.setup() 10 | features.if_feature_enabled({ "alpha", "plugin.feature.tabnine_chat" }, function() 11 | user_commands.setup() 12 | auto_commands.setup() 13 | chat.setup() 14 | end) 15 | 16 | if config.is_enterprise() then 17 | user_commands.setup() 18 | auto_commands.setup() 19 | chat.setup() 20 | end 21 | end 22 | 23 | return M 24 | -------------------------------------------------------------------------------- /.github/workflows/lua-format-check-pr.yml: -------------------------------------------------------------------------------- 1 | name: Check Lint With Stylua 2 | on: 3 | pull_request: 4 | paths: 5 | - "**.lua" 6 | permissions: 7 | contents: read 8 | checks: write 9 | issues: write 10 | pull-requests: write 11 | jobs: 12 | format_code: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: JohnnyMorganz/stylua-action@v4 17 | with: 18 | token: ${{ secrets.GITHUB_TOKEN }} 19 | version: latest 20 | args: . 21 | - name: suggester 22 | uses: reviewdog/action-suggester@v1 23 | with: 24 | tool_name: stylua 25 | fail_on_error: true 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEATURE]" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/workflows/chat.yaml: -------------------------------------------------------------------------------- 1 | name: Chat 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | env: 7 | CARGO_TERM_COLOR: always 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | target: [x86_64-unknown-linux-musl] 15 | 16 | steps: 17 | - name: add gtk 18 | run: sudo apt-get install -y libgtk2.0-dev libglib2.0-dev 19 | - uses: actions/checkout@v4 20 | - uses: actions-rs/toolchain@v1 21 | with: 22 | toolchain: 1.70.0 23 | target: ${{ matrix.target }} 24 | - uses: ClementTsang/cargo-action@v0.0.3 25 | with: 26 | command: build 27 | args: --release --target=${{ matrix.target }} 28 | use-cross: true 29 | directory: "./chat" 30 | -------------------------------------------------------------------------------- /lua/tabnine/config.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local config = {} 3 | 4 | function M.set_config(o) 5 | config = vim.tbl_deep_extend("force", { 6 | disable_auto_comment = false, 7 | accept_keymap = "", 8 | dismiss_keymap = "", 9 | debounce_ms = 800, 10 | suggestion_color = { gui = "#808080", cterm = 244 }, 11 | codelens_color = { gui = "#808080", cterm = 244 }, 12 | codelens_enabled = true, 13 | exclude_filetypes = { "TelescopePrompt", "NvimTree" }, 14 | log_file_path = nil, 15 | tabnine_enterprise_host = nil, 16 | ignore_certificate_errors = false, 17 | workspace_folders = { 18 | paths = {}, 19 | lsp = true, 20 | get_paths = nil, 21 | }, 22 | }, o or {}) 23 | end 24 | 25 | function M.get_config() 26 | return config 27 | end 28 | 29 | function M.is_enterprise() 30 | return config.tabnine_enterprise_host ~= nil 31 | end 32 | 33 | return M 34 | -------------------------------------------------------------------------------- /lua/tabnine/workspace.lua: -------------------------------------------------------------------------------- 1 | local tabnine_binary = require("tabnine.binary") 2 | local uv = vim.uv or vim.loop 3 | local lsp = vim.lsp 4 | local config = require("tabnine.config") 5 | local utils = require("tabnine.utils") 6 | 7 | local M = {} 8 | 9 | local function workspace_folders() 10 | local config = config.get_config().workspace_folders 11 | local result = {} 12 | 13 | if config.lsp and #utils.buf_get_clients() > 0 then 14 | vim.list_extend(result, utils.set(lsp.buf.list_workspace_folders())) 15 | end 16 | 17 | if config.paths then vim.list_extend(result, config.paths) end 18 | 19 | if config.get_paths then vim.list_extend(result, config.get_paths() or {}) end 20 | 21 | return result 22 | end 23 | 24 | function M.update() 25 | tabnine_binary:request({ Workspace = { root_paths = workspace_folders() } }, function() end) 26 | end 27 | 28 | function M.setup() 29 | local timer = uv.new_timer() 30 | 31 | timer:start(0, 30000, vim.schedule_wrap(M.update)) 32 | end 33 | 34 | return M 35 | -------------------------------------------------------------------------------- /lua/tabnine/chat/user_commands.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local api = vim.api 3 | local apply = require("tabnine.chat.apply") 4 | local chat = require("tabnine.chat") 5 | local codelens = require("tabnine.chat.codelens") 6 | 7 | function M.setup() 8 | api.nvim_create_user_command("TabnineChat", function() 9 | chat.open() 10 | end, {}) 11 | api.nvim_create_user_command("TabnineChatClose", chat.close, {}) 12 | api.nvim_create_user_command("TabnineChatClear", chat.clear_conversation, {}) 13 | api.nvim_create_user_command("TabnineChatNew", chat.new_conversation, {}) 14 | api.nvim_create_user_command("TabnineExplain", function() 15 | codelens.run_under_cursor("/explain-code") 16 | end, {}) 17 | api.nvim_create_user_command("TabnineTest", function() 18 | codelens.run_under_cursor("/generate-test-for-code") 19 | end, {}) 20 | api.nvim_create_user_command("TabnineFix", function() 21 | codelens.run_under_cursor("/fix-code") 22 | end, {}) 23 | api.nvim_create_user_command("TabnineAccept", apply.accept, {}) 24 | api.nvim_create_user_command("TabnineReject", apply.reject, {}) 25 | end 26 | 27 | return M 28 | -------------------------------------------------------------------------------- /lua/tabnine/chat/auto_commands.lua: -------------------------------------------------------------------------------- 1 | local api = vim.api 2 | local chat = require("tabnine.chat") 3 | local codelens = require("tabnine.chat.codelens") 4 | local utils = require("tabnine.utils") 5 | local workspace = require("tabnine.workspace") 6 | local M = {} 7 | 8 | function M.setup() 9 | api.nvim_create_autocmd("VimLeavePre", { 10 | pattern = "*", 11 | callback = function() 12 | if chat.is_open() then chat.close() end 13 | end, 14 | }) 15 | 16 | api.nvim_create_autocmd({ "CursorMoved", "ModeChanged" }, { 17 | pattern = "*", 18 | callback = utils.debounce(function() 19 | if codelens.should_display() then 20 | pcall(codelens.collect_symbols, codelens.reload) 21 | else 22 | codelens.clear() 23 | end 24 | end, 100), 25 | }) 26 | 27 | api.nvim_create_autocmd({ "BufEnter" }, { 28 | pattern = "*", 29 | callback = codelens.reload_buf_supports_symbols, 30 | }) 31 | 32 | api.nvim_create_autocmd({ "LspAttach" }, { 33 | pattern = "*", 34 | callback = function() 35 | workspace.update() 36 | codelens.reload_buf_supports_symbols() 37 | end, 38 | }) 39 | end 40 | 41 | return M 42 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: "" 6 | assignees: "" 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Version Info:** 24 | 25 | - OS (try `cat /etc/os-release`): 26 | - Neovim version (`nvim -v`): 27 | - Installed Tabnine Binaries (`ls -A /path/to/plugin/binaries`): 28 | - Active Tabnine Binaries (`cat /path/to/plugin/binaries/.active`): 29 | 30 | 37 | 38 | **Additional context** 39 | Add any other context about the problem here. 40 | -------------------------------------------------------------------------------- /lua/tabnine.lua: -------------------------------------------------------------------------------- 1 | local auto_commands = require("tabnine.auto_commands") 2 | local chat_setup = require("tabnine.chat.setup") 3 | local config = require("tabnine.config") 4 | local consts = require("tabnine.consts") 5 | local keymaps = require("tabnine.keymaps") 6 | local semver = require("tabnine.third_party.semver.semver") 7 | local status = require("tabnine.status") 8 | local user_commands = require("tabnine.user_commands") 9 | local workspace = require("tabnine.workspace") 10 | 11 | local M = {} 12 | 13 | function M.setup(o) 14 | config.set_config(o) 15 | 16 | local v = vim.version() 17 | local cur_version = semver(v.major, v.minor, v.patch) 18 | local min_version = semver(consts.min_nvim_version) 19 | if cur_version < min_version then 20 | vim.notify_once( 21 | string.format( 22 | "tabnine-nvim requires neovim version >=%s. Current version: %d.%d.%d", 23 | consts.min_nvim_version, 24 | v.major, 25 | v.minor, 26 | v.patch 27 | ), 28 | vim.log.levels.WARN 29 | ) 30 | return nil 31 | end 32 | 33 | keymaps.setup() 34 | 35 | user_commands.setup() 36 | 37 | auto_commands.setup() 38 | 39 | status.setup() 40 | 41 | chat_setup.setup() 42 | 43 | workspace.setup() 44 | end 45 | 46 | return M 47 | -------------------------------------------------------------------------------- /chat/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.js": "/static/js/main.71883e5c.js", 4 | "static/media/search-global.svg": "/static/media/search-global.44b8a34d33afb11043eb9c4be126b367.svg", 5 | "static/media/wrap-lines.svg": "/static/media/wrap-lines.13a09e50def53862a2ad716f022a89b4.svg", 6 | "static/media/regenerate-icon.svg": "/static/media/regenerate-icon.23ca2ef0b7bc604e52452e95988b605f.svg", 7 | "static/media/thumbs-down.svg": "/static/media/thumbs-down.e3ce4e31142dca108a7dac87b278812f.svg", 8 | "static/media/thumbs-up.svg": "/static/media/thumbs-up.986fa7d7a6adcca59140bfbfe792d3a5.svg", 9 | "index.html": "/index.html", 10 | "static/media/search-repo.svg": "/static/media/search-repo.a9cd85257b80abbe796d805b358a6ea5.svg", 11 | "static/media/insert.svg": "/static/media/insert.1f71d5be4c4c93408123ba3d78dabd1f.svg", 12 | "static/media/copy-icon.svg": "/static/media/copy-icon.897dbfda2c63c95f7d674d264b2e838b.svg", 13 | "static/media/abort.svg": "/static/media/abort.63c869e32e3040f9df852d44d39058b8.svg", 14 | "static/media/right-arrow.svg": "/static/media/right-arrow.1822c754c41f6e0054c1353a70eb4f95.svg", 15 | "main.71883e5c.js.map": "/static/js/main.71883e5c.js.map" 16 | }, 17 | "entrypoints": [ 18 | "static/js/main.71883e5c.js" 19 | ] 20 | } -------------------------------------------------------------------------------- /lua/tabnine/keymaps.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local completion = require("tabnine.completion") 3 | local config = require("tabnine.config") 4 | local state = require("tabnine.state") 5 | 6 | ---@return boolean 7 | function M.has_suggestion() 8 | return state.active == true and state.completions_cache ~= nil 9 | end 10 | M.accept_suggestion = vim.schedule_wrap(function() 11 | if not M.has_suggestion() then return end 12 | return completion.accept() 13 | end) 14 | M.dismiss_suggestion = vim.schedule_wrap(function() 15 | if not M.has_suggestion() then return end 16 | completion.clear() 17 | state.completions_cache = nil 18 | end) 19 | 20 | function M.setup() 21 | local accept_keymap = config.get_config().accept_keymap 22 | local dismiss_keymap = config.get_config().dismiss_keymap 23 | if accept_keymap then -- allow setting to `false` to disable 24 | vim.keymap.set("i", accept_keymap, function() 25 | if not M.has_suggestion() then return accept_keymap end 26 | return M.accept_suggestion() 27 | end, { expr = true }) 28 | end 29 | 30 | if dismiss_keymap then -- allow setting to `false` to disable 31 | vim.keymap.set("i", dismiss_keymap, function() 32 | if not M.has_suggestion() then return dismiss_keymap end 33 | return M.dismiss_suggestion() 34 | end, { expr = true }) 35 | end 36 | end 37 | 38 | return M 39 | -------------------------------------------------------------------------------- /dl_binaries.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env -S pwsh -noprofile -nologo 2 | 3 | # This script downloads the binaries for the most recent version of TabNine. 4 | 5 | $TABNINE_UPDATE_SERVICE="https://update.tabnine.com" 6 | if ($args.count -gt 0) { 7 | $TABNINE_UPDATE_SERVICE=$args[0] 8 | } 9 | 10 | if ($null -ne $env:version) { 11 | $version=$Env:version 12 | } 13 | else { 14 | $version = invoke-webrequest -uri "$TABNINE_UPDATE_SERVICE/bundles/version" -usebasicparsing 15 | } 16 | 17 | if ([Environment]::Is64BitOperatingSystem) { 18 | $targets = @( 19 | 'x86_64-pc-windows-gnu' 20 | ) 21 | } 22 | else { 23 | $targets = @( 24 | 'i686-pc-windows-gnu' 25 | ) 26 | } 27 | 28 | if (test-path -path "binaries/$version") { 29 | remove-item -path binaries -recurse -force | out-null 30 | New-Item -Path "binaries/$version" -ItemType Directory -force | out-null 31 | } 32 | 33 | $targets | foreach-object { 34 | $target = $_ 35 | $path = "$version/$target" 36 | 37 | if (!(test-path -path "binaries/$version/$target")) { New-Item -Path "binaries/$version/$target" -ItemType Directory -force | out-null } 38 | 39 | Write-Output "downloading $path" 40 | invoke-webrequest -uri "$TABNINE_UPDATE_SERVICE/bundles/$path/TabNine.zip" -outfile "binaries/$path/TabNine.zip" 41 | # Stop this iteration if the download failed 42 | if (!(Test-Path "binaries/$path/TabNine.zip" -PathType Leaf)) {return} 43 | 44 | expand-archive "binaries/$path/TabNine.zip" "binaries/$path" 45 | 46 | remove-item -path "binaries/$path/TabNine.zip" 47 | } 48 | -------------------------------------------------------------------------------- /lua/tabnine/auto_commands.lua: -------------------------------------------------------------------------------- 1 | local api = vim.api 2 | local completion = require("tabnine.completion") 3 | local config = require("tabnine.config") 4 | local consts = require("tabnine.consts") 5 | local state = require("tabnine.state") 6 | 7 | local M = {} 8 | 9 | function M.setup() 10 | -- CursorMoved is only triggered in Normal or Visual - see ':h CursorMoved' 11 | api.nvim_create_autocmd({ "InsertLeave", "CursorMoved" }, { pattern = "*", callback = completion.clear }) 12 | 13 | if config.get_config().disable_auto_comment then 14 | api.nvim_create_autocmd("FileType", { 15 | pattern = "*", 16 | command = "setlocal formatoptions-=c formatoptions-=r formatoptions-=o", 17 | }) 18 | end 19 | 20 | api.nvim_create_autocmd({ "VimEnter", "ColorScheme" }, { 21 | pattern = "*", 22 | callback = function() 23 | api.nvim_set_hl(0, consts.tabnine_hl_group, { 24 | fg = config.get_config().suggestion_color.gui, 25 | ctermfg = config.get_config().suggestion_color.cterm, 26 | }) 27 | 28 | api.nvim_set_hl(0, consts.tabnine_codelens_hl_group, { 29 | fg = config.get_config().codelens_color.gui, 30 | ctermfg = config.get_config().codelens_color.cterm, 31 | }) 32 | end, 33 | }) 34 | 35 | api.nvim_create_autocmd("BufEnter", { 36 | pattern = "*", 37 | callback = function() 38 | if completion.should_prefetch() then completion.prefetch() end 39 | end, 40 | }) 41 | 42 | api.nvim_create_autocmd("CursorMovedI", { 43 | pattern = "*", 44 | callback = function() 45 | if completion.should_complete() then 46 | completion.complete() 47 | else 48 | completion.clear() 49 | state.completions_cache = nil 50 | end 51 | end, 52 | }) 53 | end 54 | 55 | return M 56 | -------------------------------------------------------------------------------- /dl_binaries.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | TABNINE_UPDATE_SERVICE=${1:-"https://update.tabnine.com"} 5 | DEPENDS='unzip curl' # list of dependencies (commands) 6 | HAS_ALL_DEPS=1 # 1 = present, 0 = missing 7 | for dep in ${DEPENDS}; do 8 | if ! command -v "$dep" >/dev/null 2>/dev/null; then # if command not accessible 9 | echo "ERROR: $dep is required to download Tabnine binaries. Please install $dep and run this again." >&2 10 | HAS_ALL_DEPS=0 11 | fi 12 | done 13 | if [ "${HAS_ALL_DEPS}" -eq 0 ]; then # missing something. 14 | exit 1 15 | fi 16 | 17 | # This script downloads the binaries for the most recent version of TabNine. 18 | # Infrastructure detection heavily inspired by https://github.com/tzachar/cmp-tabnine/blob/main/install.sh 19 | version=${version:-$(curl -fsSL "$TABNINE_UPDATE_SERVICE/bundles/version")} 20 | case $(uname -s) in 21 | "Darwin") 22 | if [ "$(uname -m)" = "arm64" ]; then 23 | targets="aarch64-apple-darwin" 24 | elif [ "$(uname -m)" = "x86_64" ]; then 25 | targets="x86_64-apple-darwin" 26 | fi 27 | ;; 28 | "Linux") 29 | if [ "$(uname -m)" = "x86_64" ]; then 30 | targets="x86_64-unknown-linux-musl" 31 | elif [ "$(uname -m)" = "aarch64" ]; then 32 | targets="aarch64-unknown-linux-musl" 33 | fi 34 | ;; 35 | esac 36 | 37 | if [ -z "$targets" ]; then 38 | echo "Target detection failed. Installing all targets" 39 | targets='x86_64-apple-darwin 40 | x86_64-unknown-linux-musl 41 | aarch64-unknown-linux-musl 42 | aarch64-apple-darwin' 43 | fi 44 | 45 | rm -rf ./binaries 46 | 47 | echo "$targets" | while read -r target; do 48 | mkdir -p "binaries/$version/$target" 49 | path=$version/$target 50 | echo "downloading $path" 51 | curl -fsSL "$TABNINE_UPDATE_SERVICE/bundles/$path/TabNine.zip" -o "binaries/$path/TabNine.zip" || 52 | continue 53 | unzip -o "binaries/$path/TabNine.zip" -d "binaries/$path" 54 | rm "binaries/$path/TabNine.zip" 55 | chmod +x "binaries/$path/"* 56 | done 57 | -------------------------------------------------------------------------------- /lua/tabnine/status.lua: -------------------------------------------------------------------------------- 1 | local uv = vim.uv or vim.loop 2 | local fn = vim.fn 3 | local utils = require("tabnine.utils") 4 | 5 | local M = {} 6 | local DISABLED_FILE = utils.module_dir() .. "/.disabled" 7 | local config = require("tabnine.config") 8 | local state = require("tabnine.state") 9 | local tabnine_binary = require("tabnine.binary") 10 | local service_level = nil 11 | local status_prefix = "⌬ tabnine" 12 | 13 | local function poll_service_level() 14 | local timer = uv.new_timer() 15 | timer:start( 16 | 0, 17 | 5000, 18 | vim.schedule_wrap(function() 19 | tabnine_binary:request({ State = { dummy_property = true } }, function(response) 20 | if response and (response.service_level == "Pro" or response.service_level == "Trial") then 21 | service_level = "pro" 22 | elseif response and response.service_level == "Business" then 23 | service_level = "enterprise" 24 | elseif response and response.service_level == "Dev" then 25 | service_level = "dev" 26 | else 27 | service_level = "basic" 28 | end 29 | end) 30 | end) 31 | ) 32 | end 33 | 34 | function M.setup() 35 | if config.is_enterprise() then 36 | service_level = "enterprise" 37 | else 38 | poll_service_level() 39 | end 40 | local _, disabled_file_exists = pcall(fn.filereadable, DISABLED_FILE) 41 | state.active = disabled_file_exists == 0 42 | end 43 | 44 | function M.enable_tabnine() 45 | pcall(fn.delete, DISABLED_FILE) 46 | state.active = true 47 | end 48 | 49 | function M.disable_tabnine() 50 | pcall(fn.writefile, { "" }, DISABLED_FILE, "b") 51 | state.active = false 52 | end 53 | 54 | function M.toggle_tabnine() 55 | if state.active then 56 | M.disable_tabnine() 57 | else 58 | M.enable_tabnine() 59 | end 60 | end 61 | 62 | function M.status() 63 | if state.active == false then return status_prefix .. " disabled" end 64 | 65 | if not service_level then return status_prefix .. " loading" end 66 | 67 | return status_prefix .. " " .. service_level 68 | end 69 | 70 | return M 71 | -------------------------------------------------------------------------------- /lua/tabnine/user_commands.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local api = vim.api 3 | local chat = require("tabnine.chat") 4 | local config = require("tabnine.config") 5 | local status = require("tabnine.status") 6 | local tabnine_binary = require("tabnine.binary") 7 | -- local ts_utls = require("nvim-treesitter.ts_utils") 8 | 9 | function M.setup() 10 | if not config.is_enterprise() then 11 | api.nvim_create_user_command("TabnineHub", function() 12 | tabnine_binary:request({ Configuration = { quiet = false } }, function() end) 13 | end, {}) 14 | 15 | api.nvim_create_user_command("TabnineHubUrl", function() 16 | tabnine_binary:request({ Configuration = { quiet = true } }, function(response) 17 | print(response.message) 18 | end) 19 | end, {}) 20 | 21 | api.nvim_create_user_command("TabnineWhoAmI", function() 22 | tabnine_binary:request({ State = { quiet = false } }, function(response) 23 | print(response.user_name) 24 | end) 25 | end, {}) 26 | else 27 | api.nvim_create_user_command("TabnineWhoAmI", function() 28 | tabnine_binary:request({ UserInfo = { quiet = false } }, function(response) 29 | print(response.email) 30 | end) 31 | end, {}) 32 | end 33 | 34 | api.nvim_create_user_command("TabnineLoginWithAuthToken", function() 35 | tabnine_binary:request({ LoginWithCustomTokenUrl = { dummy = true } }, function(url) 36 | vim.ui.input({ 37 | prompt = string.format("Get your token from: %s\nPaste it here: ", url), 38 | }, function(custom_token) 39 | tabnine_binary:request({ 40 | LoginWithCustomToken = { custom_token = custom_token }, 41 | }, function(response) 42 | if response.is_success then 43 | vim.notify("Logged in successfully") 44 | else 45 | vim.notify("Sign in failed", vim.log.levels.WARN) 46 | end 47 | end) 48 | end) 49 | end) 50 | end, {}) 51 | 52 | api.nvim_create_user_command("TabnineLogin", function() 53 | tabnine_binary:request({ Login = { dummy = true } }, function() end) 54 | end, {}) 55 | 56 | api.nvim_create_user_command("TabnineLogout", function() 57 | tabnine_binary:request({ Logout = { dummy = true } }, function() end) 58 | end, {}) 59 | 60 | api.nvim_create_user_command("TabnineEnable", status.enable_tabnine, {}) 61 | api.nvim_create_user_command("TabnineDisable", status.disable_tabnine, {}) 62 | api.nvim_create_user_command("TabnineToggle", status.toggle_tabnine, {}) 63 | api.nvim_create_user_command("TabnineStatus", function() 64 | print(status.status()) 65 | end, {}) 66 | end 67 | 68 | return M 69 | -------------------------------------------------------------------------------- /lua/tabnine/chat/codelens.lua: -------------------------------------------------------------------------------- 1 | local chat = require("tabnine.chat") 2 | local config = require("tabnine.config") 3 | local consts = require("tabnine.consts") 4 | local lsp = require("tabnine.lsp") 5 | local state = require("tabnine.state") 6 | local utils = require("tabnine.utils") 7 | local api = vim.api 8 | local fn = vim.fn 9 | 10 | local M = {} 11 | local current_symbols = {} 12 | local symbol_under_cursor = nil 13 | local cancel_lsp_request = nil 14 | local buf_supports_symbols = false 15 | 16 | function M.reload_buf_supports_symbols() 17 | buf_supports_symbols = utils.buf_support_symbols() 18 | end 19 | 20 | function M.should_display() 21 | return config.get_config().codelens_enabled 22 | and state.active 23 | and not vim.tbl_contains(config.get_config().exclude_filetypes, vim.bo.filetype) 24 | and buf_supports_symbols 25 | end 26 | 27 | function M.collect_symbols(on_collect) 28 | if cancel_lsp_request then cancel_lsp_request() end 29 | cancel_lsp_request = lsp.get_document_symbols("", function(symbols) 30 | current_symbols = symbols 31 | on_collect() 32 | end) 33 | end 34 | 35 | function M.run_under_cursor(command) 36 | if not symbol_under_cursor then return end 37 | chat.open(function() 38 | utils.select_range({ 39 | { 40 | symbol_under_cursor.range.start.line + 1, 41 | symbol_under_cursor.range.start.character + 1, 42 | }, 43 | { 44 | symbol_under_cursor.range["end"].line + 1, 45 | symbol_under_cursor.range["end"].character + 1, 46 | }, 47 | }) 48 | chat.submit_message(command) 49 | chat.focus() 50 | end) 51 | end 52 | 53 | local function is_symbol_under_cursor(symbol) 54 | local line = fn.line(".") 55 | return symbol.range and line > symbol.range.start.line and line <= symbol.range["end"].line + 1 56 | end 57 | 58 | function M.clear() 59 | symbol_under_cursor = nil 60 | api.nvim_buf_clear_namespace(0, consts.tabnine_codelens_namespace, 0, -1) 61 | end 62 | 63 | function M.reload() 64 | local new_symbol_under_cursor = nil 65 | for _, symbol in ipairs(current_symbols) do 66 | if is_symbol_under_cursor(symbol) then new_symbol_under_cursor = symbol end 67 | end 68 | 69 | if new_symbol_under_cursor == symbol_under_cursor then return end 70 | 71 | if not new_symbol_under_cursor then 72 | M.clear() 73 | elseif new_symbol_under_cursor then 74 | M.clear() 75 | api.nvim_buf_set_extmark( 76 | 0, 77 | consts.tabnine_codelens_namespace, 78 | new_symbol_under_cursor.range.start.line, 79 | 0, 80 | { virt_text = { { "⌬ tabnine {}", consts.tabnine_codelens_hl_group } } } 81 | ) 82 | end 83 | symbol_under_cursor = new_symbol_under_cursor 84 | end 85 | 86 | return M 87 | -------------------------------------------------------------------------------- /lua/tabnine/lsp.lua: -------------------------------------------------------------------------------- 1 | local utils = require("tabnine.utils") 2 | local M = {} 3 | 4 | M.SYMBOL_KIND = { FILE = 0, FUNCTION = 12, CLASS = 5, METHOD = 6 } 5 | 6 | local function is_not_source(symbol_path) 7 | local dirs = { "node_modules", "dist", "build", "target", "out" } 8 | for i, dir in ipairs(dirs) do 9 | if string.sub(symbol_path, 1, string.len(dir)) == dir then return true end 10 | end 11 | return false 12 | end 13 | 14 | local function flatten_symbols(symbols, result) 15 | result = result or {} 16 | 17 | for _, symbol in ipairs(symbols) do 18 | table.insert(result, symbol) 19 | 20 | if symbol.children then flatten_symbols(symbol.children, result) end 21 | end 22 | 23 | return result 24 | end 25 | 26 | local EXCLUDE_FILE_PATHS = { 27 | "node_modules/", 28 | "\\.git/", 29 | "\\.vscode", 30 | "dist/", 31 | "\\.log$", 32 | "\\.tmp$", 33 | "\\.DS_Store$", 34 | "__pycache__/", 35 | "\\.class$", 36 | } 37 | 38 | local function get_files_as_workspace_symbols(query, max_num_of_results) 39 | local files = {} 40 | for _, relative_path in ipairs(vim.fn.glob("**/" .. query, true, true)) do 41 | for _, exclude_pattern in ipairs(EXCLUDE_FILE_PATHS) do 42 | if relative_path:match(exclude_pattern) then goto glob_loop end 43 | end 44 | table.insert(files, { 45 | kind = M.SYMBOL_KIND.FILE, 46 | relativePath = relative_path, 47 | name = vim.fn.fnamemodify(relative_path, ":t"), 48 | containerName = "", 49 | location = { 50 | uri = vim.fn.getcwd() .. "/" .. relative_path, 51 | range = { start = { line = 0, character = 0 }, ["end"] = { line = -1, character = -1 } }, 52 | }, 53 | }) 54 | ::glob_loop:: 55 | end 56 | return files 57 | end 58 | 59 | function M.get_workspace_symbols(query, callback) 60 | local params = { query = query } 61 | local files_symbols = get_files_as_workspace_symbols(query) 62 | return vim.lsp.buf_request_all(0, "workspace/symbol", params, function(responses) 63 | local results = {} 64 | for _, response in ipairs(responses) do 65 | if response.result then 66 | for _, result in ipairs(flatten_symbols(response.result)) do 67 | result.location.uri = utils.remove_matching_prefix(result.location.uri, "file://") 68 | if 69 | ( 70 | result.kind == M.SYMBOL_KIND.CLASS 71 | or result.kind == M.SYMBOL_KIND.METHOD 72 | or result.kind == M.SYMBOL_KIND.FUNCTION 73 | ) 74 | and utils.starts_with(result.location.uri, vim.fn.getcwd()) 75 | and not is_not_source(result.location.uri) 76 | then 77 | table.insert(results, result) 78 | end 79 | end 80 | end 81 | end 82 | callback(vim.tbl_extend("force", results, files_symbols)) 83 | end) 84 | end 85 | 86 | function M.get_document_symbols(query, callback) 87 | local params = { 88 | textDocument = vim.lsp.util.make_text_document_params(), 89 | } 90 | return vim.lsp.buf_request_all(0, "textDocument/documentSymbol", params, function(responses) 91 | local results = {} 92 | for _, response in ipairs(responses) do 93 | if response.result then 94 | for _, result in ipairs(flatten_symbols(response.result)) do 95 | if 96 | ( 97 | result.kind == M.SYMBOL_KIND.CLASS 98 | or result.kind == M.SYMBOL_KIND.METHOD 99 | or result.kind == M.SYMBOL_KIND.FUNCTION 100 | ) and utils.starts_with(result.name, query) 101 | then 102 | table.insert(results, result) 103 | end 104 | end 105 | end 106 | end 107 | callback(results) 108 | end) 109 | end 110 | 111 | return M 112 | -------------------------------------------------------------------------------- /lua/tabnine/chat/binary.lua: -------------------------------------------------------------------------------- 1 | local uv = vim.uv or vim.loop 2 | local json = vim.json 3 | local utils = require("tabnine.utils") 4 | local ChatBinary = {} 5 | local on_closed_callbacks = {} 6 | 7 | local function binary_name() 8 | local os_uname = uv.os_uname() 9 | if os_uname.sysname == "Windows_NT" then 10 | return "tabnine_chat.exe" 11 | else 12 | return "tabnine_chat" 13 | end 14 | end 15 | 16 | local binary_path = utils.module_dir() .. "/chat/target/release/" .. binary_name() 17 | 18 | function ChatBinary:available() 19 | return vim.fn.executable(binary_path) == 1 20 | end 21 | 22 | function ChatBinary:close() 23 | if self.handle and not self.handle:is_closing() then 24 | self.handle:close() 25 | uv.kill(self.pid, "sigterm") 26 | self.handle = nil 27 | self.pid = nil 28 | self.stdin = nil 29 | uv.read_stop(self.stdout) 30 | uv.read_stop(self.stderr) 31 | self.stdout = nil 32 | self.stderr = nil 33 | end 34 | end 35 | 36 | function ChatBinary:is_open() 37 | if self.handle == nil then return false end 38 | return self.handle:is_active() 39 | end 40 | 41 | function ChatBinary:on_closed(callback) 42 | on_closed_callbacks[#on_closed_callbacks + 1] = callback 43 | end 44 | 45 | local function on_closed() 46 | for _, callback in ipairs(on_closed_callbacks) do 47 | callback() 48 | end 49 | on_closed_callbacks = {} 50 | end 51 | 52 | function ChatBinary:start() 53 | if self.pid then return end 54 | 55 | self.stdin = uv.new_pipe() 56 | self.stdout = uv.new_pipe() 57 | self.stderr = uv.new_pipe() 58 | 59 | self.handle, self.pid = uv.spawn( 60 | binary_path, 61 | { 62 | stdio = { self.stdin, self.stdout, self.stderr }, 63 | }, 64 | vim.schedule_wrap(function(code, signal) -- on exit 65 | if signal ~= 0 or code ~= 0 then 66 | local err = "Something went wrong running Tabnine chat" 67 | if signal ~= 0 then 68 | err = err .. (" (signal %d)"):format(signal) 69 | else 70 | err = err .. (" (exit code %d)"):format(code) 71 | end 72 | vim.notify(err, vim.log.levels.WARN) 73 | end 74 | on_closed() 75 | self:close() 76 | end) 77 | ) 78 | 79 | utils.read_lines_start( 80 | self.stdout, 81 | vim.schedule_wrap(function(line) 82 | local message = vim.json.decode(line, { luanil = { object = true, array = true } }) 83 | local handler = self.registry[message.command] 84 | if handler then 85 | handler(message.data, function(payload) 86 | self:post_message({ 87 | id = message.id, 88 | payload = payload, 89 | }) 90 | end, function(error) 91 | self:post_message({ id = message.id, error = error }) 92 | end) 93 | else 94 | self:post_message({ id = message.id, error = "not_implemented" }) 95 | end 96 | end), 97 | vim.schedule_wrap(function(error) 98 | print("error reading chat binary", error) 99 | end) 100 | ) 101 | end 102 | 103 | function ChatBinary:new(o) 104 | o = o or {} 105 | setmetatable(o, self) 106 | self.__index = self 107 | self.stdin = nil 108 | self.stdout = nil 109 | self.stderr = nil 110 | self.handle = nil 111 | self.pid = nil 112 | self.registry = {} 113 | 114 | return o 115 | end 116 | 117 | function ChatBinary:register_event(event, handler) 118 | self.registry[event] = handler 119 | end 120 | 121 | function ChatBinary:post_message(message) 122 | if self.stdin then 123 | uv.write(self.stdin, json.encode(message) .. "\n") 124 | else 125 | vim.notify("tabnine chat not found, did you remember to start it first?", vim.log.levels.WARN) 126 | end 127 | end 128 | 129 | return ChatBinary:new() 130 | -------------------------------------------------------------------------------- /lua/tabnine/binary.lua: -------------------------------------------------------------------------------- 1 | local uv = vim.uv or vim.loop 2 | local fn = vim.fn 3 | local json = vim.json 4 | local consts = require("tabnine.consts") 5 | local semver = require("tabnine.third_party.semver.semver") 6 | local utils = require("tabnine.utils") 7 | local TabnineBinary = {} 8 | local config = require("tabnine.config") 9 | 10 | local api_version = "4.4.223" 11 | local binaries_path = utils.module_dir() .. "/binaries" 12 | 13 | local function arch_and_platform() 14 | local os_uname = uv.os_uname() 15 | 16 | if os_uname.sysname == "Linux" and os_uname.machine == "x86_64" then 17 | return "x86_64-unknown-linux-musl" 18 | elseif os_uname.sysname == "Linux" and os_uname.machine == "aarch64" then 19 | return "aarch64-unknown-linux-musl" 20 | elseif os_uname.sysname == "Darwin" and os_uname.machine == "arm64" then 21 | return "aarch64-apple-darwin" 22 | elseif os_uname.sysname == "Darwin" then 23 | return "x86_64-apple-darwin" 24 | elseif os_uname.sysname == "Windows_NT" and os_uname.machine == "x86_64" then 25 | return "x86_64-pc-windows-gnu" 26 | elseif os_uname.sysname == "Windows_NT" then 27 | return "i686-pc-windows-gnu" 28 | end 29 | end 30 | 31 | local function binary_name() 32 | local os_uname = uv.os_uname() 33 | if os_uname.sysname == "Windows_NT" then 34 | return "TabNine.exe" 35 | else 36 | return "TabNine" 37 | end 38 | end 39 | 40 | local function binary_path() 41 | local paths = vim.tbl_map(function(path) 42 | return fn.fnamemodify(path, ":t") 43 | end, fn.glob(binaries_path .. "/*", true, true)) 44 | 45 | paths = vim.tbl_map(function(path) 46 | return semver(path) 47 | end, paths) 48 | 49 | table.sort(paths) 50 | 51 | return binaries_path .. "/" .. tostring(paths[#paths]) .. "/" .. arch_and_platform() .. "/" .. binary_name() 52 | end 53 | 54 | local function optional_args() 55 | local config = config.get_config() 56 | local args = {} 57 | if config.log_file_path then table.insert(args, "--log-file-path=" .. config.log_file_path) end 58 | if config.tabnine_enterprise_host then table.insert(args, "--cloud2_url=" .. config.tabnine_enterprise_host) end 59 | return args 60 | end 61 | 62 | function TabnineBinary:start() 63 | local config = config.get_config() 64 | self.stdin = uv.new_pipe() 65 | self.stdout = uv.new_pipe() 66 | self.stderr = uv.new_pipe() 67 | self.handle, self.pid = uv.spawn(binary_path(), { 68 | args = vim.list_extend({ 69 | "--client", 70 | "nvim", 71 | "--client-metadata", 72 | "ide-restart-counter=" .. self.restart_counter, 73 | "pluginVersion=" .. consts.plugin_version, 74 | "--tls_config", 75 | "insecure=" .. tostring(config.ignore_certificate_errors), 76 | }, optional_args()), 77 | stdio = { self.stdin, self.stdout, self.stderr }, 78 | }, function() 79 | self.handle, self.pid = nil, nil 80 | uv.read_stop(self.stdout) 81 | end) 82 | 83 | utils.read_lines_start( 84 | self.stdout, 85 | vim.schedule_wrap(function(line) 86 | local callback = table.remove(self.callbacks) 87 | if not callback.cancelled then 88 | local decoded = vim.json.decode(line, { luanil = { object = true, array = true } }) 89 | callback.callback(decoded) 90 | end 91 | end), 92 | vim.schedule_wrap(function(error) 93 | print("tabnine binary read_start error", error) 94 | end) 95 | ) 96 | end 97 | 98 | function TabnineBinary:new(o) 99 | o = o or {} 100 | setmetatable(o, self) 101 | self.__index = self 102 | self.stdin = nil 103 | self.stdout = nil 104 | self.stderr = nil 105 | self.restart_counter = 0 106 | self.handle = nil 107 | self.pid = nil 108 | self.callbacks = {} 109 | 110 | return o 111 | end 112 | 113 | function TabnineBinary:request(request, on_response) 114 | if not self.pid then 115 | self.restart_counter = self.restart_counter + 1 116 | self:start() 117 | end 118 | uv.write(self.stdin, json.encode({ request = request, version = api_version }) .. "\n") 119 | local callback = { cancelled = false, callback = on_response } 120 | local function cancel() 121 | callback.cancelled = true 122 | end 123 | 124 | table.insert(self.callbacks, 1, callback) 125 | return cancel 126 | end 127 | 128 | return TabnineBinary:new() 129 | -------------------------------------------------------------------------------- /lua/tabnine/completion.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | local api = vim.api 3 | local fn = vim.fn 4 | local uv = vim.uv or vim.loop 5 | local config = require("tabnine.config") 6 | local consts = require("tabnine.consts") 7 | local state = require("tabnine.state") 8 | local tabnine_binary = require("tabnine.binary") 9 | local utils = require("tabnine.utils") 10 | 11 | local function valid_response(response) 12 | return response and response.results and #response.results > 0 and #response.results[1].new_prefix > 0 13 | end 14 | 15 | function M.accept() 16 | M.clear() 17 | --- Don't error if no completion available! 18 | if not state.rendered_completion or state.rendered_completion == "" then return end 19 | local lines = utils.str_to_lines(state.rendered_completion) 20 | 21 | if utils.starts_with(state.rendered_completion, "\n") then 22 | api.nvim_buf_set_lines(0, fn.line("."), fn.line("."), false, lines) 23 | api.nvim_win_set_cursor(0, { 24 | fn.line(".") + #lines, 25 | fn.col(".") + #lines[#lines], 26 | }) 27 | return 28 | end 29 | 30 | api.nvim_put(lines, "c", false, true) 31 | state.completions_cache = nil 32 | end 33 | 34 | function M.clear() 35 | if state.cancel_completion then state.cancel_completion() end 36 | state.debounce_timer:stop() 37 | api.nvim_buf_clear_namespace(0, consts.tabnine_namespace, 0, -1) 38 | end 39 | 40 | function M.should_complete() 41 | return state.active 42 | and utils.document_changed() 43 | and not vim.tbl_contains(config.get_config().exclude_filetypes, vim.bo.filetype) 44 | and consts.valid_end_of_line_regex:match_str(utils.end_of_line()) 45 | end 46 | 47 | function M.complete() 48 | local now = uv.now() 49 | local changedtick = vim.b.changedtick 50 | local before_table = api.nvim_buf_get_text(0, 0, 0, fn.line(".") - 1, fn.col(".") - 1, {}) 51 | local before = table.concat(before_table, "\n") 52 | 53 | local after_table = 54 | api.nvim_buf_get_text(0, fn.line(".") - 1, fn.col(".") - 1, fn.line("$") - 1, fn.col("$,$") - 1, {}) 55 | local after = table.concat(after_table, "\n") 56 | state.cancel_completion = tabnine_binary:request({ 57 | Autocomplete = { 58 | before = before, 59 | after = after, 60 | filename = fn.expand("%:t"), 61 | region_includes_beginning = true, 62 | region_includes_end = false, 63 | max_num_results = 1, 64 | correlation_id = state.requests_counter, 65 | }, 66 | }, function(response) 67 | M.clear() 68 | if not valid_response(response) then 69 | state.completions_cache = nil 70 | return 71 | end 72 | 73 | if 74 | state.completions_cache 75 | and utils.ends_with(state.completions_cache.results[1].new_prefix, response.results[1].new_prefix) 76 | then 77 | M.render(response.results[1].new_prefix, response.old_prefix, changedtick) 78 | return 79 | end 80 | 81 | state.completions_cache = response 82 | local debounce_ms = math.max(0, config.get_config().debounce_ms - (uv.now() - now)) 83 | state.debounce_timer:start( 84 | debounce_ms, 85 | 0, 86 | vim.schedule_wrap(function() 87 | M.render(response.results[1].new_prefix, response.old_prefix, changedtick) 88 | end) 89 | ) 90 | end) 91 | end 92 | 93 | function M.render(completion, old_prefix, changedtick) 94 | if not (vim.b.changedtick == changedtick) then return end 95 | 96 | local lines = utils.str_to_lines(completion) 97 | 98 | if utils.starts_with(completion, "\n") then 99 | local other_lines = vim.tbl_map(function(line) 100 | return { { line, consts.tabnine_hl_group } } 101 | end, lines) 102 | 103 | api.nvim_buf_set_extmark( 104 | 0, 105 | consts.tabnine_namespace, 106 | fn.line(".") - 1, 107 | fn.col(".") - 1, 108 | { virt_lines = other_lines } 109 | ) 110 | 111 | state.rendered_completion = completion 112 | return 113 | end 114 | 115 | lines[1] = lines[1]:sub(#old_prefix + 1, -1) 116 | lines[1] = utils.remove_matching_suffix(lines[1], utils.end_of_line()) 117 | 118 | local first_line = { { lines[1], consts.tabnine_hl_group } } 119 | local other_lines = vim.tbl_map(function(line) 120 | return { { line, consts.tabnine_hl_group } } 121 | end, utils.subset(lines, 2)) 122 | 123 | api.nvim_buf_set_extmark(0, consts.tabnine_namespace, fn.line(".") - 1, fn.col(".") - 1, { 124 | virt_text_win_col = fn.virtcol(".") - 1, 125 | virt_text = first_line, 126 | virt_lines = other_lines, 127 | }) 128 | 129 | state.rendered_completion = utils.lines_to_str(lines) 130 | end 131 | 132 | function M.should_prefetch() 133 | return state.active and not vim.tbl_contains(config.get_config().exclude_filetypes, vim.bo.filetype) 134 | end 135 | 136 | function M.prefetch() 137 | -- TODO add active_text_editor_changed event 138 | tabnine_binary:request({ Prefetch = { filename = api.nvim_buf_get_name(0) } }, function() end) 139 | end 140 | 141 | return M 142 | -------------------------------------------------------------------------------- /lua/tabnine/chat/apply.lua: -------------------------------------------------------------------------------- 1 | local api = vim.api 2 | local M = {} 3 | local original_window 4 | local diff_resolve_callback 5 | 6 | local function create_floating_window(width_percentage, height_percentage, col_offset) 7 | local width = math.floor(vim.o.columns * width_percentage) 8 | local height = math.floor(vim.o.lines * height_percentage) 9 | local row = math.floor((vim.o.lines - height) / 2) 10 | local col = math.floor((vim.o.columns - width) / 2) + col_offset 11 | 12 | local opts = { 13 | relative = "editor", 14 | width = width, 15 | height = height, 16 | row = row, 17 | col = col, 18 | style = "minimal", 19 | border = "rounded", 20 | } 21 | 22 | return api.nvim_open_win(0, true, opts) 23 | end 24 | 25 | M.open = function(diff, callback) 26 | original_window = api.nvim_get_current_win() 27 | diff_resolve_callback = callback 28 | if diff.comparableCode then 29 | local current_filetype = vim.bo.filetype 30 | 31 | -- Create two floating windows side by side 32 | local left_win = create_floating_window(0.4, 0.8, -math.floor(vim.o.columns * 0.2)) 33 | local right_win = create_floating_window(0.4, 0.8, math.floor(vim.o.columns * 0.2)) 34 | 35 | -- Create buffers for comparable and new code 36 | local comparable_buf = api.nvim_create_buf(false, true) 37 | local new_buf = api.nvim_create_buf(false, true) 38 | 39 | -- Set content and options for comparable code buffer 40 | api.nvim_buf_set_lines(comparable_buf, 0, -1, false, vim.split(diff.comparableCode, "\n")) 41 | api.nvim_buf_set_option(comparable_buf, "filetype", current_filetype) 42 | api.nvim_buf_set_option(comparable_buf, "modifiable", false) 43 | 44 | -- Set content and options for new code buffer 45 | api.nvim_buf_set_lines(new_buf, 0, -1, false, vim.split(diff.newCode, "\n")) 46 | api.nvim_buf_set_option(new_buf, "filetype", current_filetype) 47 | api.nvim_buf_set_option(new_buf, "modifiable", false) 48 | 49 | -- Set buffers to respective windows 50 | api.nvim_win_set_buf(left_win, comparable_buf) 51 | api.nvim_win_set_buf(right_win, new_buf) 52 | 53 | -- Enable diff mode for both windows 54 | api.nvim_win_call(left_win, function() 55 | vim.cmd("diffthis") 56 | end) 57 | api.nvim_win_call(right_win, function() 58 | vim.cmd("diffthis") 59 | end) 60 | 61 | -- Store window IDs 62 | M.comparable_win = left_win 63 | M.new_win = right_win 64 | end 65 | end 66 | 67 | M.accept = function() 68 | if 69 | M.new_win 70 | and M.comparable_win 71 | and api.nvim_win_is_valid(M.new_win) 72 | and api.nvim_win_is_valid(M.comparable_win) 73 | then 74 | local new_code_buf = api.nvim_win_get_buf(M.new_win) 75 | local comparable_code_buf = api.nvim_win_get_buf(M.comparable_win) 76 | 77 | -- Get the content of the new code buffer 78 | local new_code = api.nvim_buf_get_lines(new_code_buf, 0, -1, false) 79 | 80 | -- Get the content of the comparable code buffer 81 | local comparable_code = api.nvim_buf_get_lines(comparable_code_buf, 0, -1, false) 82 | 83 | -- Switch to the original window 84 | api.nvim_set_current_win(original_window) 85 | local original_buf = api.nvim_get_current_buf() 86 | local original_lines = api.nvim_buf_get_lines(original_buf, 0, -1, false) 87 | 88 | -- Find the start and end positions of the comparable code in the original buffer 89 | local start_line, end_line 90 | for i, line in ipairs(original_lines) do 91 | if line == comparable_code[1] then 92 | start_line = i - 1 93 | end_line = start_line + #comparable_code - 1 94 | if vim.deep_equal(vim.list_slice(original_lines, start_line + 1, end_line + 1), comparable_code) then 95 | break 96 | end 97 | end 98 | end 99 | 100 | if start_line and end_line then 101 | -- Replace only the comparable code portion with the new code 102 | api.nvim_buf_set_lines(original_buf, start_line, end_line + 1, false, new_code) 103 | end 104 | 105 | -- Close the diff windows 106 | M.close() 107 | -- Call the diff resolve callback with the new code 108 | if diff_resolve_callback then diff_resolve_callback(true) end 109 | end 110 | end 111 | 112 | M.close = function() 113 | if M.comparable_win and api.nvim_win_is_valid(M.comparable_win) then api.nvim_win_close(M.comparable_win, true) end 114 | if M.new_win and api.nvim_win_is_valid(M.new_win) then api.nvim_win_close(M.new_win, true) end 115 | M.comparable_win = nil 116 | M.new_win = nil 117 | end 118 | 119 | M.reject = function() 120 | if 121 | M.new_win 122 | and M.comparable_win 123 | and api.nvim_win_is_valid(M.new_win) 124 | and api.nvim_win_is_valid(M.comparable_win) 125 | then 126 | -- Switch back to the original window 127 | api.nvim_set_current_win(original_window) 128 | 129 | -- Close the diff windows 130 | M.close() 131 | if diff_resolve_callback then diff_resolve_callback(false) end 132 | end 133 | end 134 | 135 | return M 136 | -------------------------------------------------------------------------------- /chat/src/main.rs: -------------------------------------------------------------------------------- 1 | use image::ImageFormat; 2 | use once_cell::sync::Lazy; 3 | use regex::Regex; 4 | use serde::{Deserialize, Serialize}; 5 | use std::{ 6 | env, 7 | fs::{canonicalize, read}, 8 | io::{self, Write}, 9 | path::PathBuf, 10 | thread, 11 | }; 12 | use wry::application::window::{Icon, Window}; 13 | use wry::{ 14 | application::{ 15 | event::{Event, StartCause, WindowEvent}, 16 | event_loop::{ControlFlow, EventLoop}, 17 | window::WindowBuilder, 18 | }, 19 | webview::WebViewBuilder, 20 | }; 21 | 22 | #[derive(Deserialize, Serialize)] 23 | #[serde(tag = "command", content = "data")] 24 | enum Message { 25 | #[serde(rename = "focus")] 26 | Focus, 27 | #[serde(rename = "set_always_on_top")] 28 | SetOnTop(bool), 29 | } 30 | 31 | const WINDOW_TITLE: &str = "Tabnine Chat"; 32 | 33 | const BASE_URL: &str = "wry://localhost"; 34 | 35 | static INDEX_HTML: Lazy = Lazy::new(|| { 36 | let index_html = read(PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("./index.html")).unwrap(); 37 | Regex::new("(href|src)=\"/static") 38 | .unwrap() 39 | .replace_all( 40 | &String::from_utf8(index_html).unwrap(), 41 | format!("$1=\"{BASE_URL}/static"), 42 | ) 43 | .to_string() 44 | }); 45 | 46 | static ICON: Lazy = Lazy::new(|| { 47 | let bytes: Vec = include_bytes!("../icon.png").to_vec(); 48 | let imagebuffer = image::load_from_memory_with_format(&bytes, ImageFormat::Png) 49 | .unwrap() 50 | .into_rgba8(); 51 | let (icon_width, icon_height) = imagebuffer.dimensions(); 52 | let icon_rgba = imagebuffer.into_raw(); 53 | Icon::from_rgba(icon_rgba, icon_width, icon_height).unwrap() 54 | }); 55 | 56 | fn main() -> wry::Result<()> { 57 | // println!("{}", serde_json::to_string_pretty(&Message::Focus).unwrap()); 58 | let event_loop = EventLoop::with_user_event(); 59 | let window = WindowBuilder::new() 60 | .with_title(WINDOW_TITLE) 61 | .with_window_icon(Some(ICON.clone())) 62 | .build(&event_loop)?; 63 | let webview = WebViewBuilder::new(window)? 64 | .with_devtools(true) 65 | .with_clipboard(true) 66 | .with_custom_protocol("wry".into(), |request| { 67 | let path = request.uri().path(); 68 | // Read the file content from file path 69 | let content = if path == "/" { 70 | INDEX_HTML.as_bytes().into() 71 | } else { 72 | read(canonicalize( 73 | PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(&path[1..]), 74 | )?)? 75 | .into() 76 | }; 77 | 78 | let mimetype = if path.ends_with(".html") || path == "/" { 79 | "text/html" 80 | } else if path.ends_with(".js") { 81 | "text/javascript" 82 | } else { 83 | unimplemented!(); 84 | }; 85 | 86 | wry::http::Response::builder() 87 | .header(wry::http::header::CONTENT_TYPE, mimetype) 88 | .body(content) 89 | .map_err(Into::into) 90 | }) 91 | .with_ipc_handler(move |_window: &Window, req: String| { 92 | let mut lock = io::stdout().lock(); 93 | let _ = writeln!(lock, "{req}"); 94 | }) 95 | .with_url(BASE_URL)? 96 | //.with_url("http://localhost:3000")? 97 | .build()?; 98 | 99 | let proxy = event_loop.create_proxy(); 100 | thread::spawn(move || loop { 101 | let mut buffer = String::new(); 102 | io::stdin().read_line(&mut buffer).unwrap(); 103 | let _ = proxy.send_event(buffer); 104 | }); 105 | 106 | event_loop.run(move |event, _, control_flow| { 107 | *control_flow = ControlFlow::Wait; 108 | 109 | match event { 110 | Event::NewEvents(StartCause::Init) => (), 111 | Event::WindowEvent { 112 | event: WindowEvent::CloseRequested, 113 | .. 114 | } => *control_flow = ControlFlow::Exit, 115 | Event::UserEvent(message) => match serde_json::from_str::(&message) { 116 | Ok(Message::Focus) => { 117 | webview.window().set_focus(); 118 | if env::consts::OS == "linux" { 119 | let _ = std::process::Command::new("wmctrl") 120 | .args(["-a", WINDOW_TITLE]) 121 | .output(); 122 | } 123 | } 124 | Ok(Message::SetOnTop(on_top)) => { 125 | webview.window().set_always_on_top(on_top); 126 | } 127 | _ => { 128 | let _ = 129 | webview.evaluate_script(&format!("window.postMessage({message},\"*\")")); 130 | } 131 | }, 132 | _ => (), 133 | } 134 | }); 135 | } 136 | -------------------------------------------------------------------------------- /doc/tabnine.txt: -------------------------------------------------------------------------------- 1 | *tabnine-nvim.txt* Tabnine client for neovim 2 | 3 | Website: https://www.tabnine.com/ 4 | Repository: https://github.com/codota/tabnine-nvim 5 | ============================================================================== 6 | CONTENTS *tabnine-nvim-contents* 7 | 8 | Introduction |tabnine-nvim-introduction| 9 | Usage |tabnine-nvim-usage| 10 | Commands |tabnine-nvim-commands| 11 | Configuration |tabnine-nvim-configuration| 12 | Advanced keymaps |tabnine-nvim-advanced-keymaps| 13 | 14 | ============================================================================== 15 | INTRODUCTION *tabnine-nvim-introduction* 16 | 17 | tabnine-nvim is a client for neovim to interact with the Tabnine completion 18 | engine. It is installed like any other plugin, and after setup in your rc 19 | file, runs in the background to provide tab completions while you edit in 20 | neovim. 21 | 22 | ============================================================================== 23 | USAGE *tabnine-nvim-usage* 24 | 25 | NOTE: NeoVim version >= v0.7 is required. 26 | Add in init.lua: > 27 | require('tabnine').setup() 28 | or if using VimScript (ie init.vim): > 29 | lua < 72 | require('tabnine').setup({ 73 | disable_auto_comment=true, 74 | }) 75 | Properties allowed on this object are: 76 | * |disable_auto_comment| 77 | * |accept_keymap| 78 | * |dismiss_keymap| 79 | * |debounce_ms| 80 | * |suggestion_color| 81 | * |exclude_filetypes| 82 | 83 | 84 | *disable_auto_comment* - Boolean - Default: false 85 | if `true`, disables automatic comment insertion when typing new lines. 86 | 87 | See https://vim.fandom.com/wiki/Disable_automatic_comment_insertion 88 | 89 | *accept_keymap* - String - Default: "" 90 | The key to press to accept the current completion. 91 | Note: Set to `false` to disable the accept keymap 92 | 93 | *dismiss_keymap* - String - Default: "" 94 | The key to press to hide the current completion. 95 | Note: Set to `false` to disable the dismiss keymap 96 | 97 | *debounce_ms* - Integer - Default: 800 - Minumum: 0 98 | The number of milliseconds to wait between keystrokes before giving 99 | completions. Higher values will be more performant, while lower values will 100 | give faster suggestions. 101 | 102 | *suggestion_color* - Object - Default: { gui = "#808080", cterm = 244 } 103 | An object representing the color to display completions in. 104 | Set using |nvim_set_hl()| 105 | `gui`: fg color name or "#RRGGBB" 106 | `cterm`: Sets foreground of cterm color (|cterm-colors|) 107 | 108 | *exclude_filetypes* - Array - Default: { "TelescopePrompt" } 109 | A list of file types to exclude from completions. (|filetype|) 110 | Use :|setfiletype| to see available file types. 111 | 112 | *log_file_path* - String - Default: nil 113 | An absolute path to Tabnine log file. 114 | 115 | 116 | ============================================================================== 117 | ADVANCED KEYMAPS *tabnine-nvim-advanced-keymaps* 118 | 119 | You can set `accept_keymap` and `dismiss_keymap` to `false` to disable them 120 | then you can create mappings using `require('tabnine.keymaps')` 121 | >lua 122 | --- Example integration with Tabnine and LuaSnip 123 | --- falling back to inserting tab if neither has a completion 124 | vim.keymap.set("i", "", function() 125 | if require("tabnine.keymaps").has_suggestion() then 126 | return require("tabnine.keymaps").accept_suggestion() 127 | elseif require("luasnip").jumpable(1) then 128 | return require("luasnip").jump(1) 129 | else 130 | return "" 131 | end 132 | end, { expr = true }) 133 | < 134 | 135 | 136 | ============================================================================== 137 | vim:tw=78:ts=4:ft=help:norl:noet:fen:noet: 138 | -------------------------------------------------------------------------------- /lua/tabnine/utils.lua: -------------------------------------------------------------------------------- 1 | local fn = vim.fn 2 | local api = vim.api 3 | 4 | local M = {} 5 | local last_changedtick = vim.b.changedtick 6 | 7 | function M.debounce(func, delay) 8 | local timer_id 9 | return function(...) 10 | if timer_id then fn.timer_stop(timer_id) end 11 | local args = { ... } 12 | timer_id = fn.timer_start(delay, function() 13 | func(unpack(args)) 14 | end) 15 | end 16 | end 17 | 18 | function M.str_to_lines(str) 19 | return fn.split(str, "\n") 20 | end 21 | 22 | function M.lines_to_str(lines) 23 | return fn.join(lines, "\n") 24 | end 25 | 26 | function M.remove_matching_suffix(str, suffix) 27 | if not M.ends_with(str, suffix) then return str end 28 | return str:sub(1, -#suffix - 1) 29 | end 30 | 31 | function M.remove_matching_prefix(str, prefix) 32 | if not M.starts_with(str, prefix) then return str end 33 | return str:sub(#prefix + 1) 34 | end 35 | 36 | function M.subset(tbl, from, to) 37 | return { unpack(tbl, from, to) } 38 | end 39 | 40 | ---returns the directory of the running script 41 | ---@return string 42 | function M.script_dir() 43 | local str = debug.getinfo(2, "S").source:sub(2) 44 | return str:match("(.*/)") or "./" 45 | end 46 | 47 | ---returns the directory of the root of the module 48 | ---@return string 49 | function M.module_dir() 50 | -- HACK: This only works if this file is not moved! 51 | return M.script_dir() .. "../.." 52 | end 53 | 54 | function M.prequire(...) 55 | local status, lib = pcall(require, ...) 56 | if status then return lib end 57 | return nil 58 | end 59 | 60 | function M.pumvisible() 61 | local cmp = M.prequire("cmp") 62 | if cmp then 63 | return cmp.visible() 64 | else 65 | return vim.fn.pumvisible() > 0 66 | end 67 | end 68 | 69 | function M.current_position() 70 | return { fn.line("."), fn.col(".") } 71 | end 72 | 73 | function M.ends_with(str, suffix) 74 | if str == "" then return true end 75 | 76 | return str:sub(-#suffix) == suffix 77 | end 78 | 79 | function M.starts_with(str, prefix) 80 | if str == "" then return true end 81 | 82 | return str:sub(1, #prefix) == prefix 83 | end 84 | 85 | function M.is_end_of_line() 86 | return fn.col(".") == fn.col("$") 87 | end 88 | 89 | function M.end_of_line() 90 | return api.nvim_buf_get_text(0, fn.line(".") - 1, fn.col(".") - 1, fn.line(".") - 1, fn.col("$"), {})[1] 91 | end 92 | 93 | function M.document_changed() 94 | local current_changedtick = last_changedtick 95 | last_changedtick = vim.b.changedtick 96 | return last_changedtick > current_changedtick 97 | end 98 | 99 | function M.selected_text() 100 | local mode = vim.fn.mode() 101 | if mode ~= "v" and mode ~= "V" and mode ~= "" then return "" end 102 | local a_orig = vim.fn.getreg("a") 103 | vim.cmd([[silent! normal! "aygv]]) 104 | local text = vim.fn.getreg("a") 105 | vim.fn.setreg("a", a_orig) 106 | return text 107 | end 108 | 109 | function M.set(array) 110 | local set = {} 111 | local uniqueValues = {} 112 | 113 | for _, value in ipairs(array) do 114 | if not set[value] then 115 | set[value] = true 116 | table.insert(uniqueValues, value) 117 | end 118 | end 119 | 120 | return uniqueValues 121 | end 122 | 123 | ---Selects a given range of text 124 | ---@param range table 125 | ---@param selection_mode? 'charwise'|'linewise'|'blockwise'|'v'|'V'|'' 126 | function M.select_range(range, selection_mode) 127 | local start_row, start_col, end_row, end_col = range[1][1], range[1][2], range[2][1], range[2][2] 128 | 129 | local v_table = { charwise = "v", linewise = "V", blockwise = "" } 130 | selection_mode = selection_mode or "charwise" 131 | 132 | -- Normalise selection_mode 133 | selection_mode = v_table[selection_mode] or selection_mode 134 | 135 | -- enter visual mode if normal or operator-pending (no) mode 136 | -- Why? According to https://learnvimscriptthehardway.stevelosh.com/chapters/15.html 137 | -- If your operator-pending mapping ends with some text visually selected, Vim will operate on that text. 138 | -- Otherwise, Vim will operate on the text between the original cursor position and the new position. 139 | local mode = api.nvim_get_mode() 140 | if mode.mode ~= selection_mode then 141 | -- Call to `nvim_replace_termcodes()` is needed for sending appropriate command to enter blockwise mode 142 | selection_mode = vim.api.nvim_replace_termcodes(selection_mode, true, true, true) 143 | api.nvim_cmd({ cmd = "normal", bang = true, args = { selection_mode } }, {}) 144 | end 145 | 146 | api.nvim_win_set_cursor(0, { start_row, start_col - 1 }) 147 | vim.cmd("normal! o") 148 | api.nvim_win_set_cursor(0, { end_row, end_col - 1 }) 149 | end 150 | 151 | function M.read_file_into_buffer(file_path) 152 | local content = vim.fn.readfile(file_path) 153 | local bufnr = vim.api.nvim_create_buf(false, true) 154 | 155 | api.nvim_buf_set_lines(bufnr, 0, -1, false, content) 156 | 157 | return bufnr 158 | end 159 | 160 | function M.read_lines_start(stream, on_line, on_error) 161 | local buffer = "" 162 | stream:read_start(function(error, chunk) 163 | if error then 164 | on_error(error) 165 | return 166 | end 167 | -- if there's no new chunk, wait until one is recieved. 168 | if not chunk then return end 169 | buffer = buffer .. chunk 170 | while true do 171 | local start_pos = buffer:find("\n") 172 | if not start_pos then break end 173 | on_line(buffer:sub(1, start_pos - 1)) 174 | buffer = buffer:sub(start_pos + 1) 175 | end 176 | end) 177 | end 178 | 179 | --- A wrapper around vim.lsp.get_clients which support nvim 0.10 and before 180 | ---@param bufnr integer? 181 | ---@return vim.lsp.Client[] 182 | function M.buf_get_clients(bufnr) 183 | bufnr = bufnr or 0 184 | if vim.lsp.get_clients then return vim.lsp.get_clients({ bufnr = bufnr }) end 185 | return vim.lsp.buf_get_clients(bufnr) 186 | end 187 | 188 | function M.buf_support_symbols() 189 | local clients = M.buf_get_clients() 190 | 191 | for _, client in ipairs(clients) do 192 | if client.server_capabilities.documentSymbolProvider then return true end 193 | end 194 | 195 | return false 196 | end 197 | 198 | return M 199 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tabnine-nvim 2 | Tabnine client for Neovim 3 | 4 | ![Tabnine Neovim client](https://github.com/codota/tabnine-nvim/blob/master/examples/javascript.gif) 5 | 6 | ## Table of Contents 7 | 8 | 9 | 10 | - [Install](#install) 11 | - [Unix (Linux, MacOS)](#unix-linux-macos) 12 | - [Windows](#windows) 13 | - [Activate (mandatory)](#activate-mandatory) 14 | - [Activate Tabnine Pro](#activate-tabnine-pro) 15 | - [Tabnine Chat](#tabnine-chat) 16 | - [Commands](#commands) 17 | - [Tabnine Chat commands](#tabnine-chat-commands) 18 | - [`` and `nvim-cmp`](#tab-and-nvim-cmp) 19 | - [lualine integration](#lualine-integration) 20 | - [Other statusline integrations](#other-statusline-integrations) 21 | - [Tabnine Enterprise customers (self hosted only)](#tabnine-enterprise-customers-self-hosted-only) 22 | - [Keymaps examples](#keymaps-examples) 23 | 24 | 25 | 26 | ## Install 27 | 28 | **Note** this plugin requires having [Neovim](https://github.com/neovim/neovim) version >= v0.7 29 | 30 | The _Unix_ build script requires `curl` and `unzip` to be available in your `$PATH` 31 | 32 | ### Unix (Linux, MacOS) 33 | 34 | Using [vim-plug](https://github.com/junegunn/vim-plug) 35 | 36 | 1. Add the following in your `init.vim` 37 | 38 | ```vim 39 | call plug#begin() 40 | Plug 'codota/tabnine-nvim', { 'do': './dl_binaries.sh' } 41 | call plug#end() 42 | ``` 43 | 44 | 2. Restart Neovim and run `:PlugInstall` 45 | 46 | Using [packer](https://github.com/wbthomason/packer.nvim) 47 | 48 | 1. Add the following in your `init.lua`: 49 | 50 | ```lua 51 | require("packer").startup(function(use) 52 | use { 'codota/tabnine-nvim', run = "./dl_binaries.sh" } 53 | end) 54 | ``` 55 | 56 | 2. Restart Neovim and run `:PackerInstall` 57 | 58 | Using [lazy.nvim](https://github.com/folke/lazy.nvim) 59 | 60 | 1. Add the following in your `init.lua`: 61 | 62 | ```lua 63 | require("lazy").setup({ 64 | { 'codota/tabnine-nvim', build = "./dl_binaries.sh" }, 65 | }) 66 | ``` 67 | 68 | 2. Restart Neovim and run `:Lazy` 69 | 70 | ### Windows 71 | 72 | 74 | 75 | The build script needs a set execution policy. 76 | Here is an example on how to set it 77 | 78 | ```Powershell 79 | Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser 80 | ``` 81 | 82 | For more information visit 83 | [the official documentation](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.2) 84 | 85 | Windows installations need to be adjusted to utilize PowerShell. This can be accomplished by changing the `do`/`run`/`build` parameter in your plugin manager's configuration from `./dl_binaries.sh` to `pwsh.exe -file .\\dl_binaries.ps1` 86 | 87 | ```Lua 88 | -- Example using lazy.nvim 89 | -- pwsh.exe for PowerShell Core 90 | -- powershell.exe for Windows PowerShell 91 | 92 | require("lazy").setup({ 93 | { 'codota/tabnine-nvim', build = "pwsh.exe -file .\\dl_binaries.ps1" }, 94 | }) 95 | ``` 96 | 97 | If you need to use Tabnine on Windows and Unix you can change the config as follows 98 | 99 | ```lua 100 | -- Get platform dependant build script 101 | local function tabnine_build_path() 102 | -- Replace vim.uv with vim.loop if using NVIM 0.9.0 or below 103 | if vim.uv.os_uname().sysname == "Windows_NT" then 104 | return "pwsh.exe -file .\\dl_binaries.ps1" 105 | else 106 | return "./dl_binaries.sh" 107 | end 108 | end 109 | require("lazy").setup({ 110 | { 'codota/tabnine-nvim', build = tabnine_build_path()}, 111 | }) 112 | ``` 113 | 114 | --- 115 | 116 | ## Activate (mandatory) 117 | 118 | Add this later in your `init.lua`: 119 | 120 | ```lua 121 | require('tabnine').setup({ 122 | disable_auto_comment=true, 123 | accept_keymap="", 124 | dismiss_keymap = "", 125 | debounce_ms = 800, 126 | suggestion_color = {gui = "#808080", cterm = 244}, 127 | exclude_filetypes = {"TelescopePrompt", "NvimTree"}, 128 | log_file_path = nil, -- absolute path to Tabnine log file 129 | ignore_certificate_errors = false, 130 | -- workspace_folders = { 131 | -- paths = { "/your/project" }, 132 | -- get_paths = function() 133 | -- return { "/your/project" } 134 | -- end, 135 | -- }, 136 | }) 137 | ``` 138 | 139 | `init.vim` users - the activation script is `lua` code. Make sure to have it inside `lua` block: 140 | 141 | ```vim 142 | lua <", function() 154 | if require("tabnine.keymaps").has_suggestion() then 155 | return require("tabnine.keymaps").accept_suggestion() 156 | elseif require("luasnip").jumpable(1) then 157 | return require("luasnip").jump(1) 158 | else 159 | return "" 160 | end 161 | end, { expr = true }) 162 | ``` 163 | 164 | ## Activate Tabnine Pro 165 | 166 | - `:TabnineHub` - to open Tabnine Hub and log in to your account 167 | - `:TabnineLoginWithAuthToken` - to log in using auth token (for headless environments, where no browser is available) 168 | 169 | Sometimes Tabnine may fail to open the browser on Tabnine Hub, in this case use `:TabnineHubUrl` to get Tabnine Hub URL 170 | 171 | ## Tabnine Chat 172 | ![Tabnine Neovim chat](https://github.com/codota/tabnine-nvim/blob/master/examples/lua-chat.gif) 173 | Tabnine chat needs a webview to run, to use it: 174 | - You will need to build the chat from source, by executing: `cargo build --release` inside `chat/` directory. 175 | - You may be missing some dependencies to build the chat. To fix this, run the following command: 176 | ```shell 177 | $ # Debian/Ubuntu 178 | $ sudo apt-get install -y libgtk-3-dev libglib2.0-dev libjavascriptcoregtk-4.1-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev 179 | $ # Arch 180 | $ pacman -S --needed gtk3 glib2 webkit2gtk-4.1 libsoup3 181 | ``` 182 | 183 | ## Commands 184 | 185 | - `:TabnineStatus` - to print Tabnine status 186 | - `:TabnineDisable` - to disable Tabnine 187 | - `:TabnineEnable` - to enable Tabnine 188 | - `:TabnineToggle` - to toggle enable/disable 189 | - `:TabnineChat` - to launch Tabnine chat 190 | - `:TabnineLoginWithAuthToken` - to log in using auth token (for headless environments, where no browser is available) 191 | - `:TabnineAccept` - accept apply changes 192 | - `:TabnineReject` - reject apply changes 193 | 194 | ### Tabnine Chat commands 195 | - `:TabnineChat` - to open Tabnine Chat 196 | - `:TabnineFix` - to fix the function in scope 197 | - `:TabnineTest` - to generate tests for function in scope 198 | - `:TabnineExplain` - to explain the function in scope 199 | - `:TabnineAccept` - accept apply changes 200 | - `:TabnineReject` - reject apply changes 201 | 202 | ## `` and `nvim-cmp` 203 | 204 | `nvim-cmp` maps `` to navigating through pop menu items (see [here](https://github.com/hrsh7th/nvim-cmp/blob/777450fd0ae289463a14481673e26246b5e38bf2/lua/cmp/config/mapping.lua#L86)) This conflicts with Tabnine `` for inline completion. To get this sorted you can either: 205 | 206 | - Bind Tabnine inline completion to a different key using `accept_keymap` 207 | - Bind `cmp.select_next_item()` & `cmp.select_prev_item()` to different keys, e.g: `` & `` 208 | 209 | ## lualine integration 210 | 211 | This plugin exposes a lualine `tabnine` component. e.g: 212 | 213 | ```lua 214 | require('lualine').setup({ 215 | tabline = { 216 | lualine_a = {}, 217 | lualine_b = {'branch'}, 218 | lualine_c = {'filename'}, 219 | lualine_x = {}, 220 | lualine_y = {}, 221 | lualine_z = {} 222 | }, 223 | sections = {lualine_c = {'lsp_progress'}, lualine_x = {'tabnine'}} 224 | }) 225 | ``` 226 | 227 | ## Other statusline integrations 228 | 229 | To render tabnine status widget use: 230 | 231 | ```lua 232 | require('tabnine.status').status() 233 | ``` 234 | 235 | ## Tabnine Enterprise customers (self hosted only) 236 | 237 | In your `init.lua`: 238 | 239 | _these instructions are made for packer, but are pretty much the same with all package managers_ 240 | 241 | ```lua 242 | local tabnine_enterprise_host = "https://tabnine.customer.com" 243 | 244 | require("packer").startup(function(use) 245 | use { 'codota/tabnine-nvim', run = "./dl_binaries.sh " .. tabnine_enterprise_host .. "/update" } 246 | end) 247 | 248 | require('tabnine').setup({ 249 | disable_auto_comment=true, 250 | accept_keymap="", 251 | dismiss_keymap = "", 252 | debounce_ms = 800, 253 | suggestion_color = {gui = "#808080", cterm = 244}, 254 | codelens_color = { gui = "#808080", cterm = 244 }, 255 | codelens_enabled = true, 256 | exclude_filetypes = {"TelescopePrompt", "NvimTree"}, 257 | log_file_path = nil, -- absolute path to Tabnine log file, 258 | tabnine_enterprise_host = tabnine_enterprise_host, 259 | ignore_certificate_errors = false, 260 | }) 261 | ``` 262 | 263 | ## Keymaps examples 264 | 265 | ```lua 266 | api.nvim_set_keymap("x", "q", "", { noremap = true, callback = require("tabnine.chat").open }) 267 | api.nvim_set_keymap("i", "q", "", { noremap = true, callback = require("tabnine.chat").open }) 268 | api.nvim_set_keymap("n", "q", "", { noremap = true, callback = require("tabnine.chat").open }) 269 | ``` 270 | -------------------------------------------------------------------------------- /lua/tabnine/chat/init.lua: -------------------------------------------------------------------------------- 1 | local chat_binary = require("tabnine.chat.binary") 2 | local fn = vim.fn 3 | local tabnine_binary = require("tabnine.binary") 4 | local utils = require("tabnine.utils") 5 | local api = vim.api 6 | local apply = require("tabnine.chat.apply") 7 | local config = require("tabnine.config") 8 | local lsp = require("tabnine.lsp") 9 | 10 | local M = { enabled = false } 11 | 12 | local CHAT_STATE_FILE = utils.module_dir() .. "/chat_state.json" 13 | local CHAT_SETTINGS_FILE = utils.module_dir() .. "/chat_settings.json" 14 | 15 | local chat_state = nil 16 | local chat_settings = nil 17 | local initialized = false 18 | 19 | local function to_chat_symbol_kind(kind) 20 | if kind == lsp.SYMBOL_KIND.METHOD then 21 | return "Method" 22 | elseif kind == lsp.SYMBOL_KIND.FUNCTION then 23 | return "Function" 24 | elseif kind == lsp.SYMBOL_KIND.CLASS then 25 | return "Class" 26 | elseif kind == lsp.SYMBOL_KIND.FILE then 27 | return "File" 28 | else 29 | return "Other" 30 | end 31 | end 32 | local function get_diagnostics() 33 | return vim.tbl_map(function(diagnostic) 34 | return { 35 | errorMessage = diagnostic.message, 36 | lineCode = api.nvim_buf_get_lines(0, diagnostic.lnum, diagnostic.lnum + 1, true)[1], 37 | lineNumber = diagnostic.lnum + 1, 38 | } 39 | end, vim.diagnostic.get(0)) 40 | end 41 | 42 | local function read_chat_state() 43 | if fn.filereadable(CHAT_STATE_FILE) == 1 then 44 | local lines = fn.readfile(CHAT_STATE_FILE) 45 | if #lines > 0 then return vim.json.decode(lines[1], { luanil = { object = true, array = true } }) end 46 | return { conversations = {} } 47 | end 48 | return { conversations = {} } 49 | end 50 | 51 | local function read_chat_settings() 52 | if fn.filereadable(CHAT_SETTINGS_FILE) == 1 then 53 | local lines = fn.readfile(CHAT_SETTINGS_FILE) 54 | if #lines > 0 then return vim.json.decode(lines[1], { luanil = { object = true, array = true } }) end 55 | return {} 56 | end 57 | return {} 58 | end 59 | 60 | local function write_chat_state(state) 61 | fn.writefile({ vim.json.encode(state) }, CHAT_STATE_FILE) 62 | end 63 | 64 | local function write_chat_settings(settings) 65 | fn.writefile({ vim.json.encode(settings) }, CHAT_SETTINGS_FILE) 66 | end 67 | 68 | local function register_events(on_init) 69 | chat_binary:register_event("get_capabilities", function(_, answer) 70 | tabnine_binary:request({ 71 | Features = { dummy = true }, 72 | }, function(response) 73 | answer({ 74 | enabledFeatures = vim.tbl_extend("force", response.enabled_features, { "chat_inline_completions" }), 75 | }) 76 | end) 77 | end) 78 | 79 | chat_binary:register_event("workspace_folders", function(_, answer) 80 | answer({ 81 | rootPaths = { fn.getcwd() }, 82 | }) 83 | end) 84 | 85 | chat_binary:register_event("get_server_url", function(request, answer) 86 | tabnine_binary:request({ 87 | ChatCommunicatorAddress = { kind = request.kind }, 88 | }, function(response) 89 | answer({ 90 | serverUrl = response.address, 91 | }) 92 | end) 93 | end) 94 | 95 | chat_binary:register_event("init", function(_, answer) 96 | local init = { ide = "ij", isDarkTheme = true } 97 | if config.is_enterprise() then init.serverUrl = config.get_config().tabnine_enterprise_host end 98 | answer(init) 99 | if not initialized and on_init then 100 | on_init() 101 | initialized = true 102 | end 103 | end) 104 | 105 | chat_binary:register_event("clear_all_chat_conversations", function(_, answer) 106 | chat_state.conversations = {} 107 | write_chat_state(chat_state) 108 | answer(chat_state) 109 | end) 110 | 111 | chat_binary:register_event("update_chat_conversation", function(conversation) 112 | chat_state = chat_state or {} 113 | chat_state.conversations[conversation.id] = { 114 | id = conversation.id, 115 | messages = conversation.messages, 116 | } 117 | write_chat_state(chat_state) 118 | end) 119 | 120 | chat_binary:register_event("get_chat_state", function(_, answer) 121 | answer(chat_state) -- this may not work good with multiple chats 122 | end) 123 | 124 | chat_binary:register_event("get_settings", function(_, answer) 125 | answer(chat_settings) 126 | end) 127 | 128 | chat_binary:register_event("update_settings", function(settings, answer) 129 | chat_settings = settings 130 | write_chat_settings(settings) 131 | answer(nil) 132 | end) 133 | 134 | chat_binary:register_event("get_user", function(_, answer) 135 | tabnine_binary:request({ State = { dummy = true } }, function(state) 136 | answer({ 137 | token = state.access_token, 138 | username = state.user_name, 139 | avatarUrl = state.user_avatar_url, 140 | serviceLevel = state.service_level, 141 | emailVerified = state.email_verified, 142 | }) 143 | end) 144 | end) 145 | chat_binary:register_event("insert_at_cursor", function(message, answer) 146 | local lines = utils.str_to_lines(message.code) 147 | 148 | if message.diff then 149 | apply.open(message.diff, answer) 150 | return 151 | end 152 | 153 | api.nvim_buf_set_text(0, fn.line("v") - 1, fn.col("v") - 1, fn.line(".") - 1, fn.col(".") - 1, lines) 154 | answer({}) 155 | end) 156 | 157 | chat_binary:register_event("get_basic_context", function(_, answer) 158 | tabnine_binary:request({ 159 | FileMetadata = { path = vim.bo.filetype }, 160 | }, function(metadata) 161 | answer({ 162 | fileUri = api.nvim_buf_get_name(0), 163 | language = vim.bo.filetype, 164 | metadata = metadata, 165 | }) 166 | end) 167 | end) 168 | 169 | chat_binary:register_event("get_enriching_context", function(request, answer) 170 | local contextTypesSet = utils.set(request.contextTypes) 171 | local enrichingContextData = vim.tbl_map(function(contextType) 172 | if contextType == "Editor" then 173 | local file_code_table = api.nvim_buf_get_text(0, 0, 0, fn.line("$") - 1, fn.col("$,$") - 1, {}) 174 | local file_code = table.concat(file_code_table, "\n") 175 | 176 | return { 177 | type = "Editor", 178 | fileCode = file_code, 179 | path = api.nvim_buf_get_name(0), 180 | currentLineIndex = api.nvim_win_get_cursor(0)[1] - 1, 181 | } 182 | elseif contextType == "Diagnostics" then 183 | return { 184 | type = "Diagnostics", 185 | diagnostics = get_diagnostics(), 186 | } 187 | elseif contextType == "Workspace" then 188 | return { type = "Workspace" } -- not implemented 189 | elseif contextType == "NFC" then 190 | -- TODO implement 191 | return nil 192 | else 193 | return nil 194 | end 195 | end, contextTypesSet) 196 | 197 | answer({ enrichingContextData = enrichingContextData }) 198 | end) 199 | 200 | chat_binary:register_event("get_selected_code", function(_, answer) 201 | local selected_code = utils.selected_text() 202 | if selected_code and selected_code:len() > 0 then 203 | answer({ 204 | code = selected_code, 205 | startLine = vim.fn.getpos("'<")[2], 206 | endLine = vim.fn.getpos("'>")[2], 207 | }) 208 | else 209 | answer(nil) 210 | end 211 | end) 212 | 213 | chat_binary:register_event("get_symbols", function(request, answer) 214 | if not utils.buf_support_symbols() then 215 | answer({ workspaceSymbols = {}, documentSymbols = {} }) 216 | return 217 | end 218 | lsp.get_document_symbols(request.query, function(document_symbols) 219 | lsp.get_workspace_symbols(request.query, function(workspace_symbols) 220 | answer({ 221 | workspaceSymbols = vim.tbl_map(function(symbol) 222 | return { 223 | name = symbol.name, 224 | absolutePath = symbol.location.uri, 225 | relativePath = utils.remove_matching_prefix(symbol.location.uri, fn.getcwd()), 226 | kind = to_chat_symbol_kind(symbol.kind), 227 | range = { 228 | startLine = symbol.location.range.start.line, 229 | startCharacter = symbol.location.range.start.character, 230 | endLine = symbol.location.range["end"].line, 231 | endCharacter = symbol.location.range["end"].character, 232 | }, 233 | } 234 | end, workspace_symbols), 235 | documentSymbols = vim.tbl_map(function(symbol) 236 | return { 237 | name = symbol.name, 238 | absolutePath = api.nvim_buf_get_name(0), 239 | relativePath = vim.fn.expand("%"), 240 | kind = to_chat_symbol_kind(symbol.kind), 241 | range = { 242 | startLine = symbol.range.start.line, 243 | startCharacter = symbol.range.start.character, 244 | endLine = symbol.range["end"].line, 245 | endCharacter = symbol.range["end"].character, 246 | }, 247 | } 248 | end, document_symbols), 249 | }) 250 | end) 251 | end) 252 | end) 253 | 254 | chat_binary:register_event("navigate_to_location", function(request, answer, error) 255 | if fn.filereadable(request.path) == 1 then 256 | local current_buffer_path = vim.fn.expand("%:p") 257 | local requested_path = fn.fnamemodify(request.path, ":p") 258 | 259 | if current_buffer_path ~= requested_path then 260 | vim.cmd("new " .. fn.fnameescape(request.path)) 261 | else 262 | vim.cmd("buffer " .. fn.bufnr(request.path)) 263 | end 264 | 265 | answer({}) 266 | else 267 | error("File not found") 268 | end 269 | end) 270 | 271 | chat_binary:register_event("create_new_file", function(request, answer) 272 | fn.writefile({ "" }, request.path) 273 | answer({}) 274 | end) 275 | 276 | chat_binary:register_event("get_file_content", function(request, answer, error) 277 | if vim.fn.filereadable(request.filePath) == 1 then 278 | local file_content = utils.lines_to_str(vim.fn.readfile(request.filePath)) 279 | answer({ content = file_content }) 280 | else 281 | error("File not found") 282 | end 283 | end) 284 | 285 | chat_binary:register_event("browse_folder", function(_, answer) 286 | vim.ui.input({ 287 | prompt = "Select folder:\n", 288 | completion = "dir", 289 | }, function(path) 290 | answer({ path = path }) 291 | end) 292 | end) 293 | 294 | chat_binary:register_event("browse_file", function(_, answer) 295 | vim.ui.input({ 296 | prompt = "Select a file:\n", 297 | completion = "file", 298 | }, function(path) 299 | answer({ path = path, content = vim.fn.readfile(path) }) 300 | end) 301 | end) 302 | 303 | chat_binary:register_event("browse_file_v2", function(_, answer) 304 | vim.ui.input({ 305 | prompt = "Select an image:\n", 306 | completion = "file", 307 | }, function(path) 308 | path = vim.fn.expand(path) 309 | local mime_type = vim.fn.system("file --mime-type -b " .. vim.fn.shellescape(path)):gsub("%s+", "") 310 | local file_name = vim.fn.fnamemodify(path, ":t") 311 | local size_bytes = vim.fn.getfsize(path) 312 | local binary_content = vim.fn.readblob(path) 313 | local base64_content = vim.base64.encode(binary_content) 314 | answer({ 315 | path = path, 316 | mimeType = mime_type, 317 | fileName = file_name, 318 | sizeBytes = size_bytes, 319 | base64Content = base64_content, 320 | }) 321 | end) 322 | end) 323 | chat_binary:register_event("get_completions", function(request, answer) 324 | local file_extension = vim.fn.expand("%:e") 325 | tabnine_binary:request({ 326 | Autocomplete = { 327 | filename = "tabnine-chat-input." .. file_extension, 328 | before = request.before, 329 | after = "", 330 | region_includes_beginning = false, 331 | region_includes_end = false, 332 | max_num_results = 1, 333 | offset = #request.before, 334 | line = 0, 335 | character = #request.before, 336 | indentation_size = 0, 337 | -- cached_only = false, 338 | }, 339 | }, function(completion_results) 340 | if 341 | completion_results.results 342 | and completion_results.results[1] 343 | and completion_results.results[1].new_prefix 344 | then 345 | answer({ completions = { completion_results.results[1].new_prefix } }) 346 | else 347 | answer({ completions = {} }) 348 | end 349 | end) 350 | end) 351 | 352 | chat_binary:register_event("get_symbols_text", function(request, answer) 353 | answer({ 354 | symbols = vim.tbl_map(function(symbol) 355 | local buf = utils.read_file_into_buffer(symbol.absolutePath) 356 | local text = utils.lines_to_str( 357 | api.nvim_buf_get_text( 358 | buf, 359 | symbol.range.startLine, 360 | symbol.range.startCharacter, 361 | symbol.range.endLine, 362 | symbol.range.endCharacter, 363 | {} 364 | ) 365 | ) 366 | api.nvim_buf_delete(buf, { force = true }) 367 | return { id = symbol.id, snippet = text } 368 | end, request.symbols), 369 | }) 370 | end) 371 | 372 | chat_binary:register_event("send_event", function(event) 373 | tabnine_binary:request({ 374 | Event = { name = event.eventName, properties = event.properties }, 375 | }, function() end) 376 | end) 377 | 378 | chat_binary:register_event("send_to_terminal", function(request, answer) 379 | answer({ response = fn.system(request.text) }) 380 | end) 381 | end 382 | 383 | function M.clear_conversation() 384 | chat_binary:post_message({ command = "clear-conversation" }) 385 | end 386 | 387 | function M.new_conversation() 388 | M.focus() 389 | chat_binary:post_message({ command = "create-new-conversation" }) 390 | chat_binary:post_message({ command = "focus-input" }) 391 | end 392 | 393 | function M.set_always_on_top(value) 394 | chat_binary:post_message({ command = "set_always_on_top", data = value }) 395 | end 396 | 397 | function M.submit_message(message) 398 | chat_binary:post_message({ command = "submit-message", data = { input = message } }) 399 | end 400 | 401 | function M.is_open() 402 | return chat_binary:is_open() 403 | end 404 | 405 | function M.close() 406 | chat_binary:close() 407 | end 408 | 409 | function M.open(on_ready) 410 | if not M.enabled then 411 | vim.notify("Tabnine Chat is available only for Pro users") 412 | return 413 | end 414 | 415 | if not chat_binary:available() then 416 | vim.notify( 417 | "tabnine_chat binary not found, did you remember to build it first? `cargo build --release` inside `chat/` directory" 418 | ) 419 | return 420 | end 421 | 422 | if M.is_open() then 423 | M.focus() 424 | if on_ready then on_ready() end 425 | return 426 | end 427 | 428 | chat_state = read_chat_state() 429 | chat_settings = read_chat_settings() 430 | register_events(on_ready) 431 | chat_binary:start() 432 | end 433 | 434 | function M.focus() 435 | chat_binary:post_message({ command = "focus" }) 436 | end 437 | 438 | function M.setup() 439 | M.enabled = true 440 | end 441 | 442 | return M 443 | -------------------------------------------------------------------------------- /chat/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "adler" 7 | version = "1.0.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 10 | 11 | [[package]] 12 | name = "aho-corasick" 13 | version = "1.0.2" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" 16 | dependencies = [ 17 | "memchr", 18 | ] 19 | 20 | [[package]] 21 | name = "anyhow" 22 | version = "1.0.71" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" 25 | 26 | [[package]] 27 | name = "atk" 28 | version = "0.16.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "39991bc421ddf72f70159011b323ff49b0f783cc676a7287c59453da2e2531cf" 31 | dependencies = [ 32 | "atk-sys", 33 | "bitflags", 34 | "glib", 35 | "libc", 36 | ] 37 | 38 | [[package]] 39 | name = "atk-sys" 40 | version = "0.16.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "11ad703eb64dc058024f0e57ccfa069e15a413b98dbd50a1a950e743b7f11148" 43 | dependencies = [ 44 | "glib-sys", 45 | "gobject-sys", 46 | "libc", 47 | "system-deps", 48 | ] 49 | 50 | [[package]] 51 | name = "autocfg" 52 | version = "1.1.0" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 55 | 56 | [[package]] 57 | name = "base64" 58 | version = "0.21.2" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" 61 | 62 | [[package]] 63 | name = "bit_field" 64 | version = "0.10.2" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" 67 | 68 | [[package]] 69 | name = "bitflags" 70 | version = "1.3.2" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 73 | 74 | [[package]] 75 | name = "block" 76 | version = "0.1.6" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 79 | 80 | [[package]] 81 | name = "block-buffer" 82 | version = "0.10.4" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 85 | dependencies = [ 86 | "generic-array", 87 | ] 88 | 89 | [[package]] 90 | name = "bumpalo" 91 | version = "3.13.0" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" 94 | 95 | [[package]] 96 | name = "bytemuck" 97 | version = "1.13.1" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" 100 | 101 | [[package]] 102 | name = "byteorder" 103 | version = "1.4.3" 104 | source = "registry+https://github.com/rust-lang/crates.io-index" 105 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 106 | 107 | [[package]] 108 | name = "bytes" 109 | version = "1.4.0" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 112 | 113 | [[package]] 114 | name = "cairo-rs" 115 | version = "0.16.7" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "f3125b15ec28b84c238f6f476c6034016a5f6cc0221cb514ca46c532139fc97d" 118 | dependencies = [ 119 | "bitflags", 120 | "cairo-sys-rs", 121 | "glib", 122 | "libc", 123 | "once_cell", 124 | "thiserror", 125 | ] 126 | 127 | [[package]] 128 | name = "cairo-sys-rs" 129 | version = "0.16.3" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "7c48f4af05fabdcfa9658178e1326efa061853f040ce7d72e33af6885196f421" 132 | dependencies = [ 133 | "glib-sys", 134 | "libc", 135 | "system-deps", 136 | ] 137 | 138 | [[package]] 139 | name = "cc" 140 | version = "1.0.79" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 143 | 144 | [[package]] 145 | name = "cesu8" 146 | version = "1.1.0" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 149 | 150 | [[package]] 151 | name = "cfg-expr" 152 | version = "0.15.3" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "215c0072ecc28f92eeb0eea38ba63ddfcb65c2828c46311d646f1a3ff5f9841c" 155 | dependencies = [ 156 | "smallvec", 157 | "target-lexicon", 158 | ] 159 | 160 | [[package]] 161 | name = "cfg-if" 162 | version = "1.0.0" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 165 | 166 | [[package]] 167 | name = "cocoa" 168 | version = "0.24.1" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" 171 | dependencies = [ 172 | "bitflags", 173 | "block", 174 | "cocoa-foundation", 175 | "core-foundation", 176 | "core-graphics", 177 | "foreign-types", 178 | "libc", 179 | "objc", 180 | ] 181 | 182 | [[package]] 183 | name = "cocoa-foundation" 184 | version = "0.1.1" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6" 187 | dependencies = [ 188 | "bitflags", 189 | "block", 190 | "core-foundation", 191 | "core-graphics-types", 192 | "foreign-types", 193 | "libc", 194 | "objc", 195 | ] 196 | 197 | [[package]] 198 | name = "color_quant" 199 | version = "1.1.0" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 202 | 203 | [[package]] 204 | name = "combine" 205 | version = "4.6.6" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" 208 | dependencies = [ 209 | "bytes", 210 | "memchr", 211 | ] 212 | 213 | [[package]] 214 | name = "convert_case" 215 | version = "0.4.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 218 | 219 | [[package]] 220 | name = "core-foundation" 221 | version = "0.9.3" 222 | source = "registry+https://github.com/rust-lang/crates.io-index" 223 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 224 | dependencies = [ 225 | "core-foundation-sys", 226 | "libc", 227 | ] 228 | 229 | [[package]] 230 | name = "core-foundation-sys" 231 | version = "0.8.4" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" 234 | 235 | [[package]] 236 | name = "core-graphics" 237 | version = "0.22.3" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" 240 | dependencies = [ 241 | "bitflags", 242 | "core-foundation", 243 | "core-graphics-types", 244 | "foreign-types", 245 | "libc", 246 | ] 247 | 248 | [[package]] 249 | name = "core-graphics-types" 250 | version = "0.1.2" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" 253 | dependencies = [ 254 | "bitflags", 255 | "core-foundation", 256 | "libc", 257 | ] 258 | 259 | [[package]] 260 | name = "cpufeatures" 261 | version = "0.2.8" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" 264 | dependencies = [ 265 | "libc", 266 | ] 267 | 268 | [[package]] 269 | name = "crc32fast" 270 | version = "1.3.2" 271 | source = "registry+https://github.com/rust-lang/crates.io-index" 272 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 273 | dependencies = [ 274 | "cfg-if", 275 | ] 276 | 277 | [[package]] 278 | name = "crossbeam-channel" 279 | version = "0.5.8" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" 282 | dependencies = [ 283 | "cfg-if", 284 | "crossbeam-utils", 285 | ] 286 | 287 | [[package]] 288 | name = "crossbeam-deque" 289 | version = "0.8.3" 290 | source = "registry+https://github.com/rust-lang/crates.io-index" 291 | checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" 292 | dependencies = [ 293 | "cfg-if", 294 | "crossbeam-epoch", 295 | "crossbeam-utils", 296 | ] 297 | 298 | [[package]] 299 | name = "crossbeam-epoch" 300 | version = "0.9.15" 301 | source = "registry+https://github.com/rust-lang/crates.io-index" 302 | checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" 303 | dependencies = [ 304 | "autocfg", 305 | "cfg-if", 306 | "crossbeam-utils", 307 | "memoffset", 308 | "scopeguard", 309 | ] 310 | 311 | [[package]] 312 | name = "crossbeam-utils" 313 | version = "0.8.16" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" 316 | dependencies = [ 317 | "cfg-if", 318 | ] 319 | 320 | [[package]] 321 | name = "crunchy" 322 | version = "0.2.2" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 325 | 326 | [[package]] 327 | name = "crypto-common" 328 | version = "0.1.6" 329 | source = "registry+https://github.com/rust-lang/crates.io-index" 330 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 331 | dependencies = [ 332 | "generic-array", 333 | "typenum", 334 | ] 335 | 336 | [[package]] 337 | name = "cssparser" 338 | version = "0.27.2" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" 341 | dependencies = [ 342 | "cssparser-macros", 343 | "dtoa-short", 344 | "itoa 0.4.8", 345 | "matches", 346 | "phf", 347 | "proc-macro2", 348 | "quote", 349 | "smallvec", 350 | "syn 1.0.109", 351 | ] 352 | 353 | [[package]] 354 | name = "cssparser-macros" 355 | version = "0.6.1" 356 | source = "registry+https://github.com/rust-lang/crates.io-index" 357 | checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" 358 | dependencies = [ 359 | "quote", 360 | "syn 2.0.22", 361 | ] 362 | 363 | [[package]] 364 | name = "derive_more" 365 | version = "0.99.17" 366 | source = "registry+https://github.com/rust-lang/crates.io-index" 367 | checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" 368 | dependencies = [ 369 | "convert_case", 370 | "proc-macro2", 371 | "quote", 372 | "rustc_version", 373 | "syn 1.0.109", 374 | ] 375 | 376 | [[package]] 377 | name = "digest" 378 | version = "0.10.7" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 381 | dependencies = [ 382 | "block-buffer", 383 | "crypto-common", 384 | ] 385 | 386 | [[package]] 387 | name = "dispatch" 388 | version = "0.2.0" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" 391 | 392 | [[package]] 393 | name = "dtoa" 394 | version = "1.0.6" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "65d09067bfacaa79114679b279d7f5885b53295b1e2cfb4e79c8e4bd3d633169" 397 | 398 | [[package]] 399 | name = "dtoa-short" 400 | version = "0.3.4" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" 403 | dependencies = [ 404 | "dtoa", 405 | ] 406 | 407 | [[package]] 408 | name = "dunce" 409 | version = "1.0.4" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" 412 | 413 | [[package]] 414 | name = "either" 415 | version = "1.8.1" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" 418 | 419 | [[package]] 420 | name = "equivalent" 421 | version = "1.0.0" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" 424 | 425 | [[package]] 426 | name = "exr" 427 | version = "1.6.4" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "279d3efcc55e19917fff7ab3ddd6c14afb6a90881a0078465196fe2f99d08c56" 430 | dependencies = [ 431 | "bit_field", 432 | "flume", 433 | "half", 434 | "lebe", 435 | "miniz_oxide", 436 | "rayon-core", 437 | "smallvec", 438 | "zune-inflate", 439 | ] 440 | 441 | [[package]] 442 | name = "fdeflate" 443 | version = "0.3.0" 444 | source = "registry+https://github.com/rust-lang/crates.io-index" 445 | checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" 446 | dependencies = [ 447 | "simd-adler32", 448 | ] 449 | 450 | [[package]] 451 | name = "field-offset" 452 | version = "0.3.6" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" 455 | dependencies = [ 456 | "memoffset", 457 | "rustc_version", 458 | ] 459 | 460 | [[package]] 461 | name = "flate2" 462 | version = "1.0.26" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" 465 | dependencies = [ 466 | "crc32fast", 467 | "miniz_oxide", 468 | ] 469 | 470 | [[package]] 471 | name = "flume" 472 | version = "0.10.14" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" 475 | dependencies = [ 476 | "futures-core", 477 | "futures-sink", 478 | "nanorand", 479 | "pin-project", 480 | "spin", 481 | ] 482 | 483 | [[package]] 484 | name = "fnv" 485 | version = "1.0.7" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 488 | 489 | [[package]] 490 | name = "foreign-types" 491 | version = "0.3.2" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 494 | dependencies = [ 495 | "foreign-types-shared", 496 | ] 497 | 498 | [[package]] 499 | name = "foreign-types-shared" 500 | version = "0.1.1" 501 | source = "registry+https://github.com/rust-lang/crates.io-index" 502 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 503 | 504 | [[package]] 505 | name = "form_urlencoded" 506 | version = "1.2.0" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" 509 | dependencies = [ 510 | "percent-encoding", 511 | ] 512 | 513 | [[package]] 514 | name = "futf" 515 | version = "0.1.5" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" 518 | dependencies = [ 519 | "mac", 520 | "new_debug_unreachable", 521 | ] 522 | 523 | [[package]] 524 | name = "futures-channel" 525 | version = "0.3.28" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 528 | dependencies = [ 529 | "futures-core", 530 | ] 531 | 532 | [[package]] 533 | name = "futures-core" 534 | version = "0.3.28" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 537 | 538 | [[package]] 539 | name = "futures-executor" 540 | version = "0.3.28" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" 543 | dependencies = [ 544 | "futures-core", 545 | "futures-task", 546 | "futures-util", 547 | ] 548 | 549 | [[package]] 550 | name = "futures-io" 551 | version = "0.3.28" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 554 | 555 | [[package]] 556 | name = "futures-macro" 557 | version = "0.3.28" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 560 | dependencies = [ 561 | "proc-macro2", 562 | "quote", 563 | "syn 2.0.22", 564 | ] 565 | 566 | [[package]] 567 | name = "futures-sink" 568 | version = "0.3.28" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 571 | 572 | [[package]] 573 | name = "futures-task" 574 | version = "0.3.28" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 577 | 578 | [[package]] 579 | name = "futures-util" 580 | version = "0.3.28" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 583 | dependencies = [ 584 | "futures-core", 585 | "futures-macro", 586 | "futures-task", 587 | "pin-project-lite", 588 | "pin-utils", 589 | "slab", 590 | ] 591 | 592 | [[package]] 593 | name = "fxhash" 594 | version = "0.2.1" 595 | source = "registry+https://github.com/rust-lang/crates.io-index" 596 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 597 | dependencies = [ 598 | "byteorder", 599 | ] 600 | 601 | [[package]] 602 | name = "gdk" 603 | version = "0.16.2" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | checksum = "aa9cb33da481c6c040404a11f8212d193889e9b435db2c14fd86987f630d3ce1" 606 | dependencies = [ 607 | "bitflags", 608 | "cairo-rs", 609 | "gdk-pixbuf", 610 | "gdk-sys", 611 | "gio", 612 | "glib", 613 | "libc", 614 | "pango", 615 | ] 616 | 617 | [[package]] 618 | name = "gdk-pixbuf" 619 | version = "0.16.7" 620 | source = "registry+https://github.com/rust-lang/crates.io-index" 621 | checksum = "c3578c60dee9d029ad86593ed88cb40f35c1b83360e12498d055022385dd9a05" 622 | dependencies = [ 623 | "bitflags", 624 | "gdk-pixbuf-sys", 625 | "gio", 626 | "glib", 627 | "libc", 628 | ] 629 | 630 | [[package]] 631 | name = "gdk-pixbuf-sys" 632 | version = "0.16.3" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "3092cf797a5f1210479ea38070d9ae8a5b8e9f8f1be9f32f4643c529c7d70016" 635 | dependencies = [ 636 | "gio-sys", 637 | "glib-sys", 638 | "gobject-sys", 639 | "libc", 640 | "system-deps", 641 | ] 642 | 643 | [[package]] 644 | name = "gdk-sys" 645 | version = "0.16.0" 646 | source = "registry+https://github.com/rust-lang/crates.io-index" 647 | checksum = "d76354f97a913e55b984759a997b693aa7dc71068c9e98bcce51aa167a0a5c5a" 648 | dependencies = [ 649 | "cairo-sys-rs", 650 | "gdk-pixbuf-sys", 651 | "gio-sys", 652 | "glib-sys", 653 | "gobject-sys", 654 | "libc", 655 | "pango-sys", 656 | "pkg-config", 657 | "system-deps", 658 | ] 659 | 660 | [[package]] 661 | name = "gdkwayland-sys" 662 | version = "0.16.0" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "4511710212ed3020b61a8622a37aa6f0dd2a84516575da92e9b96928dcbe83ba" 665 | dependencies = [ 666 | "gdk-sys", 667 | "glib-sys", 668 | "gobject-sys", 669 | "libc", 670 | "pkg-config", 671 | "system-deps", 672 | ] 673 | 674 | [[package]] 675 | name = "gdkx11-sys" 676 | version = "0.16.0" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | checksum = "9fa2bf8b5b8c414bc5d05e48b271896d0fd3ddb57464a3108438082da61de6af" 679 | dependencies = [ 680 | "gdk-sys", 681 | "glib-sys", 682 | "libc", 683 | "system-deps", 684 | "x11", 685 | ] 686 | 687 | [[package]] 688 | name = "generic-array" 689 | version = "0.14.7" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 692 | dependencies = [ 693 | "typenum", 694 | "version_check", 695 | ] 696 | 697 | [[package]] 698 | name = "getrandom" 699 | version = "0.1.16" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 702 | dependencies = [ 703 | "cfg-if", 704 | "libc", 705 | "wasi 0.9.0+wasi-snapshot-preview1", 706 | ] 707 | 708 | [[package]] 709 | name = "getrandom" 710 | version = "0.2.10" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 713 | dependencies = [ 714 | "cfg-if", 715 | "js-sys", 716 | "libc", 717 | "wasi 0.11.0+wasi-snapshot-preview1", 718 | "wasm-bindgen", 719 | ] 720 | 721 | [[package]] 722 | name = "gif" 723 | version = "0.12.0" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" 726 | dependencies = [ 727 | "color_quant", 728 | "weezl", 729 | ] 730 | 731 | [[package]] 732 | name = "gio" 733 | version = "0.16.7" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "2a1c84b4534a290a29160ef5c6eff2a9c95833111472e824fc5cb78b513dd092" 736 | dependencies = [ 737 | "bitflags", 738 | "futures-channel", 739 | "futures-core", 740 | "futures-io", 741 | "futures-util", 742 | "gio-sys", 743 | "glib", 744 | "libc", 745 | "once_cell", 746 | "pin-project-lite", 747 | "smallvec", 748 | "thiserror", 749 | ] 750 | 751 | [[package]] 752 | name = "gio-sys" 753 | version = "0.16.3" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "e9b693b8e39d042a95547fc258a7b07349b1f0b48f4b2fa3108ba3c51c0b5229" 756 | dependencies = [ 757 | "glib-sys", 758 | "gobject-sys", 759 | "libc", 760 | "system-deps", 761 | "winapi", 762 | ] 763 | 764 | [[package]] 765 | name = "glib" 766 | version = "0.16.9" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "16aa2475c9debed5a32832cb5ff2af5a3f9e1ab9e69df58eaadc1ab2004d6eba" 769 | dependencies = [ 770 | "bitflags", 771 | "futures-channel", 772 | "futures-core", 773 | "futures-executor", 774 | "futures-task", 775 | "futures-util", 776 | "gio-sys", 777 | "glib-macros", 778 | "glib-sys", 779 | "gobject-sys", 780 | "libc", 781 | "once_cell", 782 | "smallvec", 783 | "thiserror", 784 | ] 785 | 786 | [[package]] 787 | name = "glib-macros" 788 | version = "0.16.8" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "fb1a9325847aa46f1e96ffea37611b9d51fc4827e67f79e7de502a297560a67b" 791 | dependencies = [ 792 | "anyhow", 793 | "heck", 794 | "proc-macro-crate", 795 | "proc-macro-error", 796 | "proc-macro2", 797 | "quote", 798 | "syn 1.0.109", 799 | ] 800 | 801 | [[package]] 802 | name = "glib-sys" 803 | version = "0.16.3" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "c61a4f46316d06bfa33a7ac22df6f0524c8be58e3db2d9ca99ccb1f357b62a65" 806 | dependencies = [ 807 | "libc", 808 | "system-deps", 809 | ] 810 | 811 | [[package]] 812 | name = "gobject-sys" 813 | version = "0.16.3" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "3520bb9c07ae2a12c7f2fbb24d4efc11231c8146a86956413fb1a79bb760a0f1" 816 | dependencies = [ 817 | "glib-sys", 818 | "libc", 819 | "system-deps", 820 | ] 821 | 822 | [[package]] 823 | name = "gtk" 824 | version = "0.16.2" 825 | source = "registry+https://github.com/rust-lang/crates.io-index" 826 | checksum = "e4d3507d43908c866c805f74c9dd593c0ce7ba5c38e576e41846639cdcd4bee6" 827 | dependencies = [ 828 | "atk", 829 | "bitflags", 830 | "cairo-rs", 831 | "field-offset", 832 | "futures-channel", 833 | "gdk", 834 | "gdk-pixbuf", 835 | "gio", 836 | "glib", 837 | "gtk-sys", 838 | "gtk3-macros", 839 | "libc", 840 | "once_cell", 841 | "pango", 842 | "pkg-config", 843 | ] 844 | 845 | [[package]] 846 | name = "gtk-sys" 847 | version = "0.16.0" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "89b5f8946685d5fe44497007786600c2f368ff6b1e61a16251c89f72a97520a3" 850 | dependencies = [ 851 | "atk-sys", 852 | "cairo-sys-rs", 853 | "gdk-pixbuf-sys", 854 | "gdk-sys", 855 | "gio-sys", 856 | "glib-sys", 857 | "gobject-sys", 858 | "libc", 859 | "pango-sys", 860 | "system-deps", 861 | ] 862 | 863 | [[package]] 864 | name = "gtk3-macros" 865 | version = "0.16.3" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "096eb63c6fedf03bafe65e5924595785eaf1bcb7200dac0f2cbe9c9738f05ad8" 868 | dependencies = [ 869 | "anyhow", 870 | "proc-macro-crate", 871 | "proc-macro-error", 872 | "proc-macro2", 873 | "quote", 874 | "syn 1.0.109", 875 | ] 876 | 877 | [[package]] 878 | name = "half" 879 | version = "2.3.1" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" 882 | dependencies = [ 883 | "cfg-if", 884 | "crunchy", 885 | ] 886 | 887 | [[package]] 888 | name = "hashbrown" 889 | version = "0.14.0" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" 892 | 893 | [[package]] 894 | name = "heck" 895 | version = "0.4.1" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 898 | 899 | [[package]] 900 | name = "hermit-abi" 901 | version = "0.2.6" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 904 | dependencies = [ 905 | "libc", 906 | ] 907 | 908 | [[package]] 909 | name = "html5ever" 910 | version = "0.25.2" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" 913 | dependencies = [ 914 | "log", 915 | "mac", 916 | "markup5ever", 917 | "proc-macro2", 918 | "quote", 919 | "syn 1.0.109", 920 | ] 921 | 922 | [[package]] 923 | name = "http" 924 | version = "0.2.9" 925 | source = "registry+https://github.com/rust-lang/crates.io-index" 926 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 927 | dependencies = [ 928 | "bytes", 929 | "fnv", 930 | "itoa 1.0.6", 931 | ] 932 | 933 | [[package]] 934 | name = "idna" 935 | version = "0.4.0" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" 938 | dependencies = [ 939 | "unicode-bidi", 940 | "unicode-normalization", 941 | ] 942 | 943 | [[package]] 944 | name = "image" 945 | version = "0.24.6" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" 948 | dependencies = [ 949 | "bytemuck", 950 | "byteorder", 951 | "color_quant", 952 | "exr", 953 | "gif", 954 | "jpeg-decoder", 955 | "num-rational", 956 | "num-traits", 957 | "png", 958 | "qoi", 959 | "tiff", 960 | ] 961 | 962 | [[package]] 963 | name = "indexmap" 964 | version = "2.0.0" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" 967 | dependencies = [ 968 | "equivalent", 969 | "hashbrown", 970 | ] 971 | 972 | [[package]] 973 | name = "instant" 974 | version = "0.1.12" 975 | source = "registry+https://github.com/rust-lang/crates.io-index" 976 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 977 | dependencies = [ 978 | "cfg-if", 979 | ] 980 | 981 | [[package]] 982 | name = "itoa" 983 | version = "0.4.8" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" 986 | 987 | [[package]] 988 | name = "itoa" 989 | version = "1.0.6" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 992 | 993 | [[package]] 994 | name = "javascriptcore-rs" 995 | version = "1.0.0" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "4cfcc681b896b083864a4a3c3b3ea196f14ff66b8641a68fde209c6d84434056" 998 | dependencies = [ 999 | "bitflags", 1000 | "glib", 1001 | "javascriptcore-rs-sys", 1002 | ] 1003 | 1004 | [[package]] 1005 | name = "javascriptcore-rs-sys" 1006 | version = "1.0.0" 1007 | source = "registry+https://github.com/rust-lang/crates.io-index" 1008 | checksum = "b0983ba5b3ab9a0c0918de02c42dc71f795d6de08092f88a98ce9fdfdee4ba91" 1009 | dependencies = [ 1010 | "glib-sys", 1011 | "gobject-sys", 1012 | "libc", 1013 | "system-deps", 1014 | ] 1015 | 1016 | [[package]] 1017 | name = "jni" 1018 | version = "0.20.0" 1019 | source = "registry+https://github.com/rust-lang/crates.io-index" 1020 | checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" 1021 | dependencies = [ 1022 | "cesu8", 1023 | "combine", 1024 | "jni-sys", 1025 | "log", 1026 | "thiserror", 1027 | "walkdir", 1028 | ] 1029 | 1030 | [[package]] 1031 | name = "jni-sys" 1032 | version = "0.3.0" 1033 | source = "registry+https://github.com/rust-lang/crates.io-index" 1034 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1035 | 1036 | [[package]] 1037 | name = "jpeg-decoder" 1038 | version = "0.3.0" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" 1041 | dependencies = [ 1042 | "rayon", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "js-sys" 1047 | version = "0.3.64" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" 1050 | dependencies = [ 1051 | "wasm-bindgen", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "kuchiki" 1056 | version = "0.8.1" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" 1059 | dependencies = [ 1060 | "cssparser", 1061 | "html5ever", 1062 | "matches", 1063 | "selectors", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "lazy_static" 1068 | version = "1.4.0" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1071 | 1072 | [[package]] 1073 | name = "lebe" 1074 | version = "0.5.2" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" 1077 | 1078 | [[package]] 1079 | name = "libc" 1080 | version = "0.2.146" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" 1083 | 1084 | [[package]] 1085 | name = "lock_api" 1086 | version = "0.4.10" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" 1089 | dependencies = [ 1090 | "autocfg", 1091 | "scopeguard", 1092 | ] 1093 | 1094 | [[package]] 1095 | name = "log" 1096 | version = "0.4.19" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" 1099 | 1100 | [[package]] 1101 | name = "mac" 1102 | version = "0.1.1" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" 1105 | 1106 | [[package]] 1107 | name = "malloc_buf" 1108 | version = "0.0.6" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1111 | dependencies = [ 1112 | "libc", 1113 | ] 1114 | 1115 | [[package]] 1116 | name = "markup5ever" 1117 | version = "0.10.1" 1118 | source = "registry+https://github.com/rust-lang/crates.io-index" 1119 | checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" 1120 | dependencies = [ 1121 | "log", 1122 | "phf", 1123 | "phf_codegen", 1124 | "string_cache", 1125 | "string_cache_codegen", 1126 | "tendril", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "matches" 1131 | version = "0.1.10" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" 1134 | 1135 | [[package]] 1136 | name = "memchr" 1137 | version = "2.5.0" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 1140 | 1141 | [[package]] 1142 | name = "memoffset" 1143 | version = "0.9.0" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" 1146 | dependencies = [ 1147 | "autocfg", 1148 | ] 1149 | 1150 | [[package]] 1151 | name = "miniz_oxide" 1152 | version = "0.7.1" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 1155 | dependencies = [ 1156 | "adler", 1157 | "simd-adler32", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "nanorand" 1162 | version = "0.7.0" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" 1165 | dependencies = [ 1166 | "getrandom 0.2.10", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "ndk" 1171 | version = "0.7.0" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" 1174 | dependencies = [ 1175 | "bitflags", 1176 | "jni-sys", 1177 | "ndk-sys", 1178 | "num_enum", 1179 | "raw-window-handle", 1180 | "thiserror", 1181 | ] 1182 | 1183 | [[package]] 1184 | name = "ndk-context" 1185 | version = "0.1.1" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 1188 | 1189 | [[package]] 1190 | name = "ndk-sys" 1191 | version = "0.4.1+23.1.7779620" 1192 | source = "registry+https://github.com/rust-lang/crates.io-index" 1193 | checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" 1194 | dependencies = [ 1195 | "jni-sys", 1196 | ] 1197 | 1198 | [[package]] 1199 | name = "new_debug_unreachable" 1200 | version = "1.0.4" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" 1203 | 1204 | [[package]] 1205 | name = "nodrop" 1206 | version = "0.1.14" 1207 | source = "registry+https://github.com/rust-lang/crates.io-index" 1208 | checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" 1209 | 1210 | [[package]] 1211 | name = "num-integer" 1212 | version = "0.1.45" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1215 | dependencies = [ 1216 | "autocfg", 1217 | "num-traits", 1218 | ] 1219 | 1220 | [[package]] 1221 | name = "num-rational" 1222 | version = "0.4.1" 1223 | source = "registry+https://github.com/rust-lang/crates.io-index" 1224 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 1225 | dependencies = [ 1226 | "autocfg", 1227 | "num-integer", 1228 | "num-traits", 1229 | ] 1230 | 1231 | [[package]] 1232 | name = "num-traits" 1233 | version = "0.2.15" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 1236 | dependencies = [ 1237 | "autocfg", 1238 | ] 1239 | 1240 | [[package]] 1241 | name = "num_cpus" 1242 | version = "1.15.0" 1243 | source = "registry+https://github.com/rust-lang/crates.io-index" 1244 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 1245 | dependencies = [ 1246 | "hermit-abi", 1247 | "libc", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "num_enum" 1252 | version = "0.5.11" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" 1255 | dependencies = [ 1256 | "num_enum_derive", 1257 | ] 1258 | 1259 | [[package]] 1260 | name = "num_enum_derive" 1261 | version = "0.5.11" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" 1264 | dependencies = [ 1265 | "proc-macro-crate", 1266 | "proc-macro2", 1267 | "quote", 1268 | "syn 1.0.109", 1269 | ] 1270 | 1271 | [[package]] 1272 | name = "objc" 1273 | version = "0.2.7" 1274 | source = "registry+https://github.com/rust-lang/crates.io-index" 1275 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1276 | dependencies = [ 1277 | "malloc_buf", 1278 | "objc_exception", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "objc_exception" 1283 | version = "0.1.2" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" 1286 | dependencies = [ 1287 | "cc", 1288 | ] 1289 | 1290 | [[package]] 1291 | name = "objc_id" 1292 | version = "0.1.1" 1293 | source = "registry+https://github.com/rust-lang/crates.io-index" 1294 | checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" 1295 | dependencies = [ 1296 | "objc", 1297 | ] 1298 | 1299 | [[package]] 1300 | name = "once_cell" 1301 | version = "1.18.0" 1302 | source = "registry+https://github.com/rust-lang/crates.io-index" 1303 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" 1304 | 1305 | [[package]] 1306 | name = "pango" 1307 | version = "0.16.5" 1308 | source = "registry+https://github.com/rust-lang/crates.io-index" 1309 | checksum = "cdff66b271861037b89d028656184059e03b0b6ccb36003820be19f7200b1e94" 1310 | dependencies = [ 1311 | "bitflags", 1312 | "gio", 1313 | "glib", 1314 | "libc", 1315 | "once_cell", 1316 | "pango-sys", 1317 | ] 1318 | 1319 | [[package]] 1320 | name = "pango-sys" 1321 | version = "0.16.3" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "9e134909a9a293e04d2cc31928aa95679c5e4df954d0b85483159bd20d8f047f" 1324 | dependencies = [ 1325 | "glib-sys", 1326 | "gobject-sys", 1327 | "libc", 1328 | "system-deps", 1329 | ] 1330 | 1331 | [[package]] 1332 | name = "parking_lot" 1333 | version = "0.12.1" 1334 | source = "registry+https://github.com/rust-lang/crates.io-index" 1335 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1336 | dependencies = [ 1337 | "lock_api", 1338 | "parking_lot_core", 1339 | ] 1340 | 1341 | [[package]] 1342 | name = "parking_lot_core" 1343 | version = "0.9.8" 1344 | source = "registry+https://github.com/rust-lang/crates.io-index" 1345 | checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" 1346 | dependencies = [ 1347 | "cfg-if", 1348 | "libc", 1349 | "redox_syscall", 1350 | "smallvec", 1351 | "windows-targets", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "percent-encoding" 1356 | version = "2.3.0" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" 1359 | 1360 | [[package]] 1361 | name = "phf" 1362 | version = "0.8.0" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" 1365 | dependencies = [ 1366 | "phf_macros", 1367 | "phf_shared 0.8.0", 1368 | "proc-macro-hack", 1369 | ] 1370 | 1371 | [[package]] 1372 | name = "phf_codegen" 1373 | version = "0.8.0" 1374 | source = "registry+https://github.com/rust-lang/crates.io-index" 1375 | checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" 1376 | dependencies = [ 1377 | "phf_generator 0.8.0", 1378 | "phf_shared 0.8.0", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "phf_generator" 1383 | version = "0.8.0" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" 1386 | dependencies = [ 1387 | "phf_shared 0.8.0", 1388 | "rand 0.7.3", 1389 | ] 1390 | 1391 | [[package]] 1392 | name = "phf_generator" 1393 | version = "0.10.0" 1394 | source = "registry+https://github.com/rust-lang/crates.io-index" 1395 | checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" 1396 | dependencies = [ 1397 | "phf_shared 0.10.0", 1398 | "rand 0.8.5", 1399 | ] 1400 | 1401 | [[package]] 1402 | name = "phf_macros" 1403 | version = "0.8.0" 1404 | source = "registry+https://github.com/rust-lang/crates.io-index" 1405 | checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" 1406 | dependencies = [ 1407 | "phf_generator 0.8.0", 1408 | "phf_shared 0.8.0", 1409 | "proc-macro-hack", 1410 | "proc-macro2", 1411 | "quote", 1412 | "syn 1.0.109", 1413 | ] 1414 | 1415 | [[package]] 1416 | name = "phf_shared" 1417 | version = "0.8.0" 1418 | source = "registry+https://github.com/rust-lang/crates.io-index" 1419 | checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" 1420 | dependencies = [ 1421 | "siphasher", 1422 | ] 1423 | 1424 | [[package]] 1425 | name = "phf_shared" 1426 | version = "0.10.0" 1427 | source = "registry+https://github.com/rust-lang/crates.io-index" 1428 | checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" 1429 | dependencies = [ 1430 | "siphasher", 1431 | ] 1432 | 1433 | [[package]] 1434 | name = "pin-project" 1435 | version = "1.1.0" 1436 | source = "registry+https://github.com/rust-lang/crates.io-index" 1437 | checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" 1438 | dependencies = [ 1439 | "pin-project-internal", 1440 | ] 1441 | 1442 | [[package]] 1443 | name = "pin-project-internal" 1444 | version = "1.1.0" 1445 | source = "registry+https://github.com/rust-lang/crates.io-index" 1446 | checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" 1447 | dependencies = [ 1448 | "proc-macro2", 1449 | "quote", 1450 | "syn 2.0.22", 1451 | ] 1452 | 1453 | [[package]] 1454 | name = "pin-project-lite" 1455 | version = "0.2.9" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 1458 | 1459 | [[package]] 1460 | name = "pin-utils" 1461 | version = "0.1.0" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1464 | 1465 | [[package]] 1466 | name = "pkg-config" 1467 | version = "0.3.27" 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" 1469 | checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 1470 | 1471 | [[package]] 1472 | name = "png" 1473 | version = "0.17.9" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" 1476 | dependencies = [ 1477 | "bitflags", 1478 | "crc32fast", 1479 | "fdeflate", 1480 | "flate2", 1481 | "miniz_oxide", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "ppv-lite86" 1486 | version = "0.2.17" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1489 | 1490 | [[package]] 1491 | name = "precomputed-hash" 1492 | version = "0.1.1" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" 1495 | 1496 | [[package]] 1497 | name = "proc-macro-crate" 1498 | version = "1.3.1" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 1501 | dependencies = [ 1502 | "once_cell", 1503 | "toml_edit", 1504 | ] 1505 | 1506 | [[package]] 1507 | name = "proc-macro-error" 1508 | version = "1.0.4" 1509 | source = "registry+https://github.com/rust-lang/crates.io-index" 1510 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1511 | dependencies = [ 1512 | "proc-macro-error-attr", 1513 | "proc-macro2", 1514 | "quote", 1515 | "syn 1.0.109", 1516 | "version_check", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "proc-macro-error-attr" 1521 | version = "1.0.4" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1524 | dependencies = [ 1525 | "proc-macro2", 1526 | "quote", 1527 | "version_check", 1528 | ] 1529 | 1530 | [[package]] 1531 | name = "proc-macro-hack" 1532 | version = "0.5.20+deprecated" 1533 | source = "registry+https://github.com/rust-lang/crates.io-index" 1534 | checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" 1535 | 1536 | [[package]] 1537 | name = "proc-macro2" 1538 | version = "1.0.63" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" 1541 | dependencies = [ 1542 | "unicode-ident", 1543 | ] 1544 | 1545 | [[package]] 1546 | name = "qoi" 1547 | version = "0.4.1" 1548 | source = "registry+https://github.com/rust-lang/crates.io-index" 1549 | checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" 1550 | dependencies = [ 1551 | "bytemuck", 1552 | ] 1553 | 1554 | [[package]] 1555 | name = "quote" 1556 | version = "1.0.28" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" 1559 | dependencies = [ 1560 | "proc-macro2", 1561 | ] 1562 | 1563 | [[package]] 1564 | name = "rand" 1565 | version = "0.7.3" 1566 | source = "registry+https://github.com/rust-lang/crates.io-index" 1567 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1568 | dependencies = [ 1569 | "getrandom 0.1.16", 1570 | "libc", 1571 | "rand_chacha 0.2.2", 1572 | "rand_core 0.5.1", 1573 | "rand_hc", 1574 | "rand_pcg", 1575 | ] 1576 | 1577 | [[package]] 1578 | name = "rand" 1579 | version = "0.8.5" 1580 | source = "registry+https://github.com/rust-lang/crates.io-index" 1581 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1582 | dependencies = [ 1583 | "libc", 1584 | "rand_chacha 0.3.1", 1585 | "rand_core 0.6.4", 1586 | ] 1587 | 1588 | [[package]] 1589 | name = "rand_chacha" 1590 | version = "0.2.2" 1591 | source = "registry+https://github.com/rust-lang/crates.io-index" 1592 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1593 | dependencies = [ 1594 | "ppv-lite86", 1595 | "rand_core 0.5.1", 1596 | ] 1597 | 1598 | [[package]] 1599 | name = "rand_chacha" 1600 | version = "0.3.1" 1601 | source = "registry+https://github.com/rust-lang/crates.io-index" 1602 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1603 | dependencies = [ 1604 | "ppv-lite86", 1605 | "rand_core 0.6.4", 1606 | ] 1607 | 1608 | [[package]] 1609 | name = "rand_core" 1610 | version = "0.5.1" 1611 | source = "registry+https://github.com/rust-lang/crates.io-index" 1612 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1613 | dependencies = [ 1614 | "getrandom 0.1.16", 1615 | ] 1616 | 1617 | [[package]] 1618 | name = "rand_core" 1619 | version = "0.6.4" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1622 | dependencies = [ 1623 | "getrandom 0.2.10", 1624 | ] 1625 | 1626 | [[package]] 1627 | name = "rand_hc" 1628 | version = "0.2.0" 1629 | source = "registry+https://github.com/rust-lang/crates.io-index" 1630 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1631 | dependencies = [ 1632 | "rand_core 0.5.1", 1633 | ] 1634 | 1635 | [[package]] 1636 | name = "rand_pcg" 1637 | version = "0.2.1" 1638 | source = "registry+https://github.com/rust-lang/crates.io-index" 1639 | checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" 1640 | dependencies = [ 1641 | "rand_core 0.5.1", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "raw-window-handle" 1646 | version = "0.5.2" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" 1649 | 1650 | [[package]] 1651 | name = "rayon" 1652 | version = "1.7.0" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" 1655 | dependencies = [ 1656 | "either", 1657 | "rayon-core", 1658 | ] 1659 | 1660 | [[package]] 1661 | name = "rayon-core" 1662 | version = "1.11.0" 1663 | source = "registry+https://github.com/rust-lang/crates.io-index" 1664 | checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" 1665 | dependencies = [ 1666 | "crossbeam-channel", 1667 | "crossbeam-deque", 1668 | "crossbeam-utils", 1669 | "num_cpus", 1670 | ] 1671 | 1672 | [[package]] 1673 | name = "redox_syscall" 1674 | version = "0.3.5" 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" 1676 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1677 | dependencies = [ 1678 | "bitflags", 1679 | ] 1680 | 1681 | [[package]] 1682 | name = "regex" 1683 | version = "1.8.4" 1684 | source = "registry+https://github.com/rust-lang/crates.io-index" 1685 | checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" 1686 | dependencies = [ 1687 | "aho-corasick", 1688 | "memchr", 1689 | "regex-syntax", 1690 | ] 1691 | 1692 | [[package]] 1693 | name = "regex-syntax" 1694 | version = "0.7.2" 1695 | source = "registry+https://github.com/rust-lang/crates.io-index" 1696 | checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" 1697 | 1698 | [[package]] 1699 | name = "rustc_version" 1700 | version = "0.4.0" 1701 | source = "registry+https://github.com/rust-lang/crates.io-index" 1702 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1703 | dependencies = [ 1704 | "semver", 1705 | ] 1706 | 1707 | [[package]] 1708 | name = "ryu" 1709 | version = "1.0.13" 1710 | source = "registry+https://github.com/rust-lang/crates.io-index" 1711 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 1712 | 1713 | [[package]] 1714 | name = "same-file" 1715 | version = "1.0.6" 1716 | source = "registry+https://github.com/rust-lang/crates.io-index" 1717 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1718 | dependencies = [ 1719 | "winapi-util", 1720 | ] 1721 | 1722 | [[package]] 1723 | name = "scopeguard" 1724 | version = "1.1.0" 1725 | source = "registry+https://github.com/rust-lang/crates.io-index" 1726 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1727 | 1728 | [[package]] 1729 | name = "selectors" 1730 | version = "0.22.0" 1731 | source = "registry+https://github.com/rust-lang/crates.io-index" 1732 | checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" 1733 | dependencies = [ 1734 | "bitflags", 1735 | "cssparser", 1736 | "derive_more", 1737 | "fxhash", 1738 | "log", 1739 | "matches", 1740 | "phf", 1741 | "phf_codegen", 1742 | "precomputed-hash", 1743 | "servo_arc", 1744 | "smallvec", 1745 | "thin-slice", 1746 | ] 1747 | 1748 | [[package]] 1749 | name = "semver" 1750 | version = "1.0.17" 1751 | source = "registry+https://github.com/rust-lang/crates.io-index" 1752 | checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" 1753 | 1754 | [[package]] 1755 | name = "serde" 1756 | version = "1.0.164" 1757 | source = "registry+https://github.com/rust-lang/crates.io-index" 1758 | checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" 1759 | dependencies = [ 1760 | "serde_derive", 1761 | ] 1762 | 1763 | [[package]] 1764 | name = "serde_derive" 1765 | version = "1.0.164" 1766 | source = "registry+https://github.com/rust-lang/crates.io-index" 1767 | checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" 1768 | dependencies = [ 1769 | "proc-macro2", 1770 | "quote", 1771 | "syn 2.0.22", 1772 | ] 1773 | 1774 | [[package]] 1775 | name = "serde_json" 1776 | version = "1.0.99" 1777 | source = "registry+https://github.com/rust-lang/crates.io-index" 1778 | checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" 1779 | dependencies = [ 1780 | "itoa 1.0.6", 1781 | "ryu", 1782 | "serde", 1783 | ] 1784 | 1785 | [[package]] 1786 | name = "serde_spanned" 1787 | version = "0.6.3" 1788 | source = "registry+https://github.com/rust-lang/crates.io-index" 1789 | checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" 1790 | dependencies = [ 1791 | "serde", 1792 | ] 1793 | 1794 | [[package]] 1795 | name = "servo_arc" 1796 | version = "0.1.1" 1797 | source = "registry+https://github.com/rust-lang/crates.io-index" 1798 | checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" 1799 | dependencies = [ 1800 | "nodrop", 1801 | "stable_deref_trait", 1802 | ] 1803 | 1804 | [[package]] 1805 | name = "sha2" 1806 | version = "0.10.7" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" 1809 | dependencies = [ 1810 | "cfg-if", 1811 | "cpufeatures", 1812 | "digest", 1813 | ] 1814 | 1815 | [[package]] 1816 | name = "simd-adler32" 1817 | version = "0.3.5" 1818 | source = "registry+https://github.com/rust-lang/crates.io-index" 1819 | checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" 1820 | 1821 | [[package]] 1822 | name = "siphasher" 1823 | version = "0.3.10" 1824 | source = "registry+https://github.com/rust-lang/crates.io-index" 1825 | checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" 1826 | 1827 | [[package]] 1828 | name = "slab" 1829 | version = "0.4.8" 1830 | source = "registry+https://github.com/rust-lang/crates.io-index" 1831 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 1832 | dependencies = [ 1833 | "autocfg", 1834 | ] 1835 | 1836 | [[package]] 1837 | name = "smallvec" 1838 | version = "1.10.0" 1839 | source = "registry+https://github.com/rust-lang/crates.io-index" 1840 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 1841 | 1842 | [[package]] 1843 | name = "soup3" 1844 | version = "0.3.2" 1845 | source = "registry+https://github.com/rust-lang/crates.io-index" 1846 | checksum = "82bc46048125fefd69d30b32b9d263d6556c9ffe82a7a7df181a86d912da5616" 1847 | dependencies = [ 1848 | "bitflags", 1849 | "futures-channel", 1850 | "gio", 1851 | "glib", 1852 | "libc", 1853 | "once_cell", 1854 | "soup3-sys", 1855 | ] 1856 | 1857 | [[package]] 1858 | name = "soup3-sys" 1859 | version = "0.3.1" 1860 | source = "registry+https://github.com/rust-lang/crates.io-index" 1861 | checksum = "014bbeb1c4cdb30739dc181e8d98b7908f124d9555843afa89b5570aaf4ec62b" 1862 | dependencies = [ 1863 | "gio-sys", 1864 | "glib-sys", 1865 | "gobject-sys", 1866 | "libc", 1867 | "system-deps", 1868 | ] 1869 | 1870 | [[package]] 1871 | name = "spin" 1872 | version = "0.9.8" 1873 | source = "registry+https://github.com/rust-lang/crates.io-index" 1874 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1875 | dependencies = [ 1876 | "lock_api", 1877 | ] 1878 | 1879 | [[package]] 1880 | name = "stable_deref_trait" 1881 | version = "1.2.0" 1882 | source = "registry+https://github.com/rust-lang/crates.io-index" 1883 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1884 | 1885 | [[package]] 1886 | name = "string_cache" 1887 | version = "0.8.7" 1888 | source = "registry+https://github.com/rust-lang/crates.io-index" 1889 | checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" 1890 | dependencies = [ 1891 | "new_debug_unreachable", 1892 | "once_cell", 1893 | "parking_lot", 1894 | "phf_shared 0.10.0", 1895 | "precomputed-hash", 1896 | "serde", 1897 | ] 1898 | 1899 | [[package]] 1900 | name = "string_cache_codegen" 1901 | version = "0.5.2" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" 1904 | dependencies = [ 1905 | "phf_generator 0.10.0", 1906 | "phf_shared 0.10.0", 1907 | "proc-macro2", 1908 | "quote", 1909 | ] 1910 | 1911 | [[package]] 1912 | name = "syn" 1913 | version = "1.0.109" 1914 | source = "registry+https://github.com/rust-lang/crates.io-index" 1915 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1916 | dependencies = [ 1917 | "proc-macro2", 1918 | "quote", 1919 | "unicode-ident", 1920 | ] 1921 | 1922 | [[package]] 1923 | name = "syn" 1924 | version = "2.0.22" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" 1927 | dependencies = [ 1928 | "proc-macro2", 1929 | "quote", 1930 | "unicode-ident", 1931 | ] 1932 | 1933 | [[package]] 1934 | name = "system-deps" 1935 | version = "6.1.1" 1936 | source = "registry+https://github.com/rust-lang/crates.io-index" 1937 | checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" 1938 | dependencies = [ 1939 | "cfg-expr", 1940 | "heck", 1941 | "pkg-config", 1942 | "toml", 1943 | "version-compare", 1944 | ] 1945 | 1946 | [[package]] 1947 | name = "tabnine_chat" 1948 | version = "0.1.0" 1949 | dependencies = [ 1950 | "image", 1951 | "once_cell", 1952 | "regex", 1953 | "serde", 1954 | "serde_json", 1955 | "wry", 1956 | ] 1957 | 1958 | [[package]] 1959 | name = "tao" 1960 | version = "0.20.0" 1961 | source = "registry+https://github.com/rust-lang/crates.io-index" 1962 | checksum = "511428fc831c0b02629c7c160ecb07a4fec54fa7d95571d280c4fbd41779720a" 1963 | dependencies = [ 1964 | "bitflags", 1965 | "cairo-rs", 1966 | "cc", 1967 | "cocoa", 1968 | "core-foundation", 1969 | "core-graphics", 1970 | "crossbeam-channel", 1971 | "dispatch", 1972 | "gdk", 1973 | "gdk-pixbuf", 1974 | "gdk-sys", 1975 | "gdkwayland-sys", 1976 | "gdkx11-sys", 1977 | "gio", 1978 | "glib", 1979 | "glib-sys", 1980 | "gtk", 1981 | "image", 1982 | "instant", 1983 | "jni", 1984 | "lazy_static", 1985 | "libc", 1986 | "log", 1987 | "ndk", 1988 | "ndk-context", 1989 | "ndk-sys", 1990 | "objc", 1991 | "once_cell", 1992 | "parking_lot", 1993 | "png", 1994 | "raw-window-handle", 1995 | "scopeguard", 1996 | "serde", 1997 | "tao-macros", 1998 | "unicode-segmentation", 1999 | "uuid", 2000 | "windows", 2001 | "windows-implement", 2002 | "x11-dl", 2003 | ] 2004 | 2005 | [[package]] 2006 | name = "tao-macros" 2007 | version = "0.1.1" 2008 | source = "registry+https://github.com/rust-lang/crates.io-index" 2009 | checksum = "3b27a4bcc5eb524658234589bdffc7e7bfb996dbae6ce9393bfd39cb4159b445" 2010 | dependencies = [ 2011 | "proc-macro2", 2012 | "quote", 2013 | "syn 1.0.109", 2014 | ] 2015 | 2016 | [[package]] 2017 | name = "target-lexicon" 2018 | version = "0.12.8" 2019 | source = "registry+https://github.com/rust-lang/crates.io-index" 2020 | checksum = "1b1c7f239eb94671427157bd93b3694320f3668d4e1eff08c7285366fd777fac" 2021 | 2022 | [[package]] 2023 | name = "tendril" 2024 | version = "0.4.3" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" 2027 | dependencies = [ 2028 | "futf", 2029 | "mac", 2030 | "utf-8", 2031 | ] 2032 | 2033 | [[package]] 2034 | name = "thin-slice" 2035 | version = "0.1.1" 2036 | source = "registry+https://github.com/rust-lang/crates.io-index" 2037 | checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" 2038 | 2039 | [[package]] 2040 | name = "thiserror" 2041 | version = "1.0.40" 2042 | source = "registry+https://github.com/rust-lang/crates.io-index" 2043 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" 2044 | dependencies = [ 2045 | "thiserror-impl", 2046 | ] 2047 | 2048 | [[package]] 2049 | name = "thiserror-impl" 2050 | version = "1.0.40" 2051 | source = "registry+https://github.com/rust-lang/crates.io-index" 2052 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" 2053 | dependencies = [ 2054 | "proc-macro2", 2055 | "quote", 2056 | "syn 2.0.22", 2057 | ] 2058 | 2059 | [[package]] 2060 | name = "tiff" 2061 | version = "0.8.1" 2062 | source = "registry+https://github.com/rust-lang/crates.io-index" 2063 | checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" 2064 | dependencies = [ 2065 | "flate2", 2066 | "jpeg-decoder", 2067 | "weezl", 2068 | ] 2069 | 2070 | [[package]] 2071 | name = "tinyvec" 2072 | version = "1.6.0" 2073 | source = "registry+https://github.com/rust-lang/crates.io-index" 2074 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 2075 | dependencies = [ 2076 | "tinyvec_macros", 2077 | ] 2078 | 2079 | [[package]] 2080 | name = "tinyvec_macros" 2081 | version = "0.1.1" 2082 | source = "registry+https://github.com/rust-lang/crates.io-index" 2083 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2084 | 2085 | [[package]] 2086 | name = "toml" 2087 | version = "0.7.5" 2088 | source = "registry+https://github.com/rust-lang/crates.io-index" 2089 | checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" 2090 | dependencies = [ 2091 | "serde", 2092 | "serde_spanned", 2093 | "toml_datetime", 2094 | "toml_edit", 2095 | ] 2096 | 2097 | [[package]] 2098 | name = "toml_datetime" 2099 | version = "0.6.3" 2100 | source = "registry+https://github.com/rust-lang/crates.io-index" 2101 | checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" 2102 | dependencies = [ 2103 | "serde", 2104 | ] 2105 | 2106 | [[package]] 2107 | name = "toml_edit" 2108 | version = "0.19.11" 2109 | source = "registry+https://github.com/rust-lang/crates.io-index" 2110 | checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" 2111 | dependencies = [ 2112 | "indexmap", 2113 | "serde", 2114 | "serde_spanned", 2115 | "toml_datetime", 2116 | "winnow", 2117 | ] 2118 | 2119 | [[package]] 2120 | name = "typenum" 2121 | version = "1.16.0" 2122 | source = "registry+https://github.com/rust-lang/crates.io-index" 2123 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 2124 | 2125 | [[package]] 2126 | name = "unicode-bidi" 2127 | version = "0.3.13" 2128 | source = "registry+https://github.com/rust-lang/crates.io-index" 2129 | checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" 2130 | 2131 | [[package]] 2132 | name = "unicode-ident" 2133 | version = "1.0.9" 2134 | source = "registry+https://github.com/rust-lang/crates.io-index" 2135 | checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" 2136 | 2137 | [[package]] 2138 | name = "unicode-normalization" 2139 | version = "0.1.22" 2140 | source = "registry+https://github.com/rust-lang/crates.io-index" 2141 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 2142 | dependencies = [ 2143 | "tinyvec", 2144 | ] 2145 | 2146 | [[package]] 2147 | name = "unicode-segmentation" 2148 | version = "1.10.1" 2149 | source = "registry+https://github.com/rust-lang/crates.io-index" 2150 | checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" 2151 | 2152 | [[package]] 2153 | name = "url" 2154 | version = "2.4.0" 2155 | source = "registry+https://github.com/rust-lang/crates.io-index" 2156 | checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" 2157 | dependencies = [ 2158 | "form_urlencoded", 2159 | "idna", 2160 | "percent-encoding", 2161 | ] 2162 | 2163 | [[package]] 2164 | name = "utf-8" 2165 | version = "0.7.6" 2166 | source = "registry+https://github.com/rust-lang/crates.io-index" 2167 | checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 2168 | 2169 | [[package]] 2170 | name = "uuid" 2171 | version = "1.3.4" 2172 | source = "registry+https://github.com/rust-lang/crates.io-index" 2173 | checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" 2174 | dependencies = [ 2175 | "getrandom 0.2.10", 2176 | ] 2177 | 2178 | [[package]] 2179 | name = "version-compare" 2180 | version = "0.1.1" 2181 | source = "registry+https://github.com/rust-lang/crates.io-index" 2182 | checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" 2183 | 2184 | [[package]] 2185 | name = "version_check" 2186 | version = "0.9.4" 2187 | source = "registry+https://github.com/rust-lang/crates.io-index" 2188 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2189 | 2190 | [[package]] 2191 | name = "walkdir" 2192 | version = "2.3.3" 2193 | source = "registry+https://github.com/rust-lang/crates.io-index" 2194 | checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" 2195 | dependencies = [ 2196 | "same-file", 2197 | "winapi-util", 2198 | ] 2199 | 2200 | [[package]] 2201 | name = "wasi" 2202 | version = "0.9.0+wasi-snapshot-preview1" 2203 | source = "registry+https://github.com/rust-lang/crates.io-index" 2204 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2205 | 2206 | [[package]] 2207 | name = "wasi" 2208 | version = "0.11.0+wasi-snapshot-preview1" 2209 | source = "registry+https://github.com/rust-lang/crates.io-index" 2210 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2211 | 2212 | [[package]] 2213 | name = "wasm-bindgen" 2214 | version = "0.2.87" 2215 | source = "registry+https://github.com/rust-lang/crates.io-index" 2216 | checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" 2217 | dependencies = [ 2218 | "cfg-if", 2219 | "wasm-bindgen-macro", 2220 | ] 2221 | 2222 | [[package]] 2223 | name = "wasm-bindgen-backend" 2224 | version = "0.2.87" 2225 | source = "registry+https://github.com/rust-lang/crates.io-index" 2226 | checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" 2227 | dependencies = [ 2228 | "bumpalo", 2229 | "log", 2230 | "once_cell", 2231 | "proc-macro2", 2232 | "quote", 2233 | "syn 2.0.22", 2234 | "wasm-bindgen-shared", 2235 | ] 2236 | 2237 | [[package]] 2238 | name = "wasm-bindgen-macro" 2239 | version = "0.2.87" 2240 | source = "registry+https://github.com/rust-lang/crates.io-index" 2241 | checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" 2242 | dependencies = [ 2243 | "quote", 2244 | "wasm-bindgen-macro-support", 2245 | ] 2246 | 2247 | [[package]] 2248 | name = "wasm-bindgen-macro-support" 2249 | version = "0.2.87" 2250 | source = "registry+https://github.com/rust-lang/crates.io-index" 2251 | checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" 2252 | dependencies = [ 2253 | "proc-macro2", 2254 | "quote", 2255 | "syn 2.0.22", 2256 | "wasm-bindgen-backend", 2257 | "wasm-bindgen-shared", 2258 | ] 2259 | 2260 | [[package]] 2261 | name = "wasm-bindgen-shared" 2262 | version = "0.2.87" 2263 | source = "registry+https://github.com/rust-lang/crates.io-index" 2264 | checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" 2265 | 2266 | [[package]] 2267 | name = "webkit2gtk" 2268 | version = "1.1.0" 2269 | source = "registry+https://github.com/rust-lang/crates.io-index" 2270 | checksum = "3ba4cce9085e0fb02575cfd45c328740dde78253cba516b1e8be2ca0f57bd8bf" 2271 | dependencies = [ 2272 | "bitflags", 2273 | "cairo-rs", 2274 | "gdk", 2275 | "gdk-sys", 2276 | "gio", 2277 | "gio-sys", 2278 | "glib", 2279 | "glib-sys", 2280 | "gobject-sys", 2281 | "gtk", 2282 | "gtk-sys", 2283 | "javascriptcore-rs", 2284 | "libc", 2285 | "once_cell", 2286 | "soup3", 2287 | "webkit2gtk-sys", 2288 | ] 2289 | 2290 | [[package]] 2291 | name = "webkit2gtk-sys" 2292 | version = "1.1.0" 2293 | source = "registry+https://github.com/rust-lang/crates.io-index" 2294 | checksum = "f4489eb24e8cf0a3d0555fd3a8f7adec2a5ece34c1e7b7c9a62da7822fd40a59" 2295 | dependencies = [ 2296 | "bitflags", 2297 | "cairo-sys-rs", 2298 | "gdk-sys", 2299 | "gio-sys", 2300 | "glib-sys", 2301 | "gobject-sys", 2302 | "gtk-sys", 2303 | "javascriptcore-rs-sys", 2304 | "libc", 2305 | "pkg-config", 2306 | "soup3-sys", 2307 | "system-deps", 2308 | ] 2309 | 2310 | [[package]] 2311 | name = "webview2-com" 2312 | version = "0.25.0" 2313 | source = "registry+https://github.com/rust-lang/crates.io-index" 2314 | checksum = "79e563ffe8e84d42e43ffacbace8780c0244fc8910346f334613559d92e203ad" 2315 | dependencies = [ 2316 | "webview2-com-macros", 2317 | "webview2-com-sys", 2318 | "windows", 2319 | "windows-implement", 2320 | "windows-interface", 2321 | ] 2322 | 2323 | [[package]] 2324 | name = "webview2-com-macros" 2325 | version = "0.7.0" 2326 | source = "registry+https://github.com/rust-lang/crates.io-index" 2327 | checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc" 2328 | dependencies = [ 2329 | "proc-macro2", 2330 | "quote", 2331 | "syn 2.0.22", 2332 | ] 2333 | 2334 | [[package]] 2335 | name = "webview2-com-sys" 2336 | version = "0.25.0" 2337 | source = "registry+https://github.com/rust-lang/crates.io-index" 2338 | checksum = "19d39576804304cf9ead192467ef47f7859a1a12fec3bd459d5ba34b8cd65ed5" 2339 | dependencies = [ 2340 | "regex", 2341 | "serde", 2342 | "serde_json", 2343 | "thiserror", 2344 | "windows", 2345 | "windows-bindgen", 2346 | "windows-metadata", 2347 | ] 2348 | 2349 | [[package]] 2350 | name = "weezl" 2351 | version = "0.1.7" 2352 | source = "registry+https://github.com/rust-lang/crates.io-index" 2353 | checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" 2354 | 2355 | [[package]] 2356 | name = "winapi" 2357 | version = "0.3.9" 2358 | source = "registry+https://github.com/rust-lang/crates.io-index" 2359 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2360 | dependencies = [ 2361 | "winapi-i686-pc-windows-gnu", 2362 | "winapi-x86_64-pc-windows-gnu", 2363 | ] 2364 | 2365 | [[package]] 2366 | name = "winapi-i686-pc-windows-gnu" 2367 | version = "0.4.0" 2368 | source = "registry+https://github.com/rust-lang/crates.io-index" 2369 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2370 | 2371 | [[package]] 2372 | name = "winapi-util" 2373 | version = "0.1.5" 2374 | source = "registry+https://github.com/rust-lang/crates.io-index" 2375 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 2376 | dependencies = [ 2377 | "winapi", 2378 | ] 2379 | 2380 | [[package]] 2381 | name = "winapi-x86_64-pc-windows-gnu" 2382 | version = "0.4.0" 2383 | source = "registry+https://github.com/rust-lang/crates.io-index" 2384 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2385 | 2386 | [[package]] 2387 | name = "windows" 2388 | version = "0.48.0" 2389 | source = "registry+https://github.com/rust-lang/crates.io-index" 2390 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 2391 | dependencies = [ 2392 | "windows-implement", 2393 | "windows-interface", 2394 | "windows-targets", 2395 | ] 2396 | 2397 | [[package]] 2398 | name = "windows-bindgen" 2399 | version = "0.48.0" 2400 | source = "registry+https://github.com/rust-lang/crates.io-index" 2401 | checksum = "1fe21a77bc54b7312dbd66f041605e098990c98be48cd52967b85b5e60e75ae6" 2402 | dependencies = [ 2403 | "windows-metadata", 2404 | "windows-tokens", 2405 | ] 2406 | 2407 | [[package]] 2408 | name = "windows-implement" 2409 | version = "0.48.0" 2410 | source = "registry+https://github.com/rust-lang/crates.io-index" 2411 | checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" 2412 | dependencies = [ 2413 | "proc-macro2", 2414 | "quote", 2415 | "syn 1.0.109", 2416 | ] 2417 | 2418 | [[package]] 2419 | name = "windows-interface" 2420 | version = "0.48.0" 2421 | source = "registry+https://github.com/rust-lang/crates.io-index" 2422 | checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" 2423 | dependencies = [ 2424 | "proc-macro2", 2425 | "quote", 2426 | "syn 1.0.109", 2427 | ] 2428 | 2429 | [[package]] 2430 | name = "windows-metadata" 2431 | version = "0.48.0" 2432 | source = "registry+https://github.com/rust-lang/crates.io-index" 2433 | checksum = "422ee0e5f0e2cc372bb6addbfff9a8add712155cd743df9c15f6ab000f31432d" 2434 | 2435 | [[package]] 2436 | name = "windows-targets" 2437 | version = "0.48.0" 2438 | source = "registry+https://github.com/rust-lang/crates.io-index" 2439 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 2440 | dependencies = [ 2441 | "windows_aarch64_gnullvm", 2442 | "windows_aarch64_msvc", 2443 | "windows_i686_gnu", 2444 | "windows_i686_msvc", 2445 | "windows_x86_64_gnu", 2446 | "windows_x86_64_gnullvm", 2447 | "windows_x86_64_msvc", 2448 | ] 2449 | 2450 | [[package]] 2451 | name = "windows-tokens" 2452 | version = "0.48.0" 2453 | source = "registry+https://github.com/rust-lang/crates.io-index" 2454 | checksum = "b34c9a3b28cb41db7385546f7f9a8179348dffc89923dde66857b1ba5312f6b4" 2455 | 2456 | [[package]] 2457 | name = "windows_aarch64_gnullvm" 2458 | version = "0.48.0" 2459 | source = "registry+https://github.com/rust-lang/crates.io-index" 2460 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 2461 | 2462 | [[package]] 2463 | name = "windows_aarch64_msvc" 2464 | version = "0.48.0" 2465 | source = "registry+https://github.com/rust-lang/crates.io-index" 2466 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 2467 | 2468 | [[package]] 2469 | name = "windows_i686_gnu" 2470 | version = "0.48.0" 2471 | source = "registry+https://github.com/rust-lang/crates.io-index" 2472 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 2473 | 2474 | [[package]] 2475 | name = "windows_i686_msvc" 2476 | version = "0.48.0" 2477 | source = "registry+https://github.com/rust-lang/crates.io-index" 2478 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 2479 | 2480 | [[package]] 2481 | name = "windows_x86_64_gnu" 2482 | version = "0.48.0" 2483 | source = "registry+https://github.com/rust-lang/crates.io-index" 2484 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 2485 | 2486 | [[package]] 2487 | name = "windows_x86_64_gnullvm" 2488 | version = "0.48.0" 2489 | source = "registry+https://github.com/rust-lang/crates.io-index" 2490 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 2491 | 2492 | [[package]] 2493 | name = "windows_x86_64_msvc" 2494 | version = "0.48.0" 2495 | source = "registry+https://github.com/rust-lang/crates.io-index" 2496 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 2497 | 2498 | [[package]] 2499 | name = "winnow" 2500 | version = "0.4.7" 2501 | source = "registry+https://github.com/rust-lang/crates.io-index" 2502 | checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" 2503 | dependencies = [ 2504 | "memchr", 2505 | ] 2506 | 2507 | [[package]] 2508 | name = "wry" 2509 | version = "0.29.0" 2510 | source = "registry+https://github.com/rust-lang/crates.io-index" 2511 | checksum = "a673852d6cefb9d1e63b7bf6f57ba728dd76ed5c06229f90b0e528fc9dffacc0" 2512 | dependencies = [ 2513 | "base64", 2514 | "block", 2515 | "cocoa", 2516 | "core-graphics", 2517 | "crossbeam-channel", 2518 | "dunce", 2519 | "gdk", 2520 | "gio", 2521 | "glib", 2522 | "gtk", 2523 | "html5ever", 2524 | "http", 2525 | "javascriptcore-rs", 2526 | "kuchiki", 2527 | "libc", 2528 | "log", 2529 | "objc", 2530 | "objc_id", 2531 | "once_cell", 2532 | "serde", 2533 | "serde_json", 2534 | "sha2", 2535 | "soup3", 2536 | "tao", 2537 | "thiserror", 2538 | "url", 2539 | "webkit2gtk", 2540 | "webkit2gtk-sys", 2541 | "webview2-com", 2542 | "windows", 2543 | "windows-implement", 2544 | ] 2545 | 2546 | [[package]] 2547 | name = "x11" 2548 | version = "2.21.0" 2549 | source = "registry+https://github.com/rust-lang/crates.io-index" 2550 | checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" 2551 | dependencies = [ 2552 | "libc", 2553 | "pkg-config", 2554 | ] 2555 | 2556 | [[package]] 2557 | name = "x11-dl" 2558 | version = "2.21.0" 2559 | source = "registry+https://github.com/rust-lang/crates.io-index" 2560 | checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" 2561 | dependencies = [ 2562 | "libc", 2563 | "once_cell", 2564 | "pkg-config", 2565 | ] 2566 | 2567 | [[package]] 2568 | name = "zune-inflate" 2569 | version = "0.2.54" 2570 | source = "registry+https://github.com/rust-lang/crates.io-index" 2571 | checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" 2572 | dependencies = [ 2573 | "simd-adler32", 2574 | ] 2575 | --------------------------------------------------------------------------------