├── denops └── @ddc-filters │ └── converter_remove_overlap │ ├── deno.json │ └── main.ts ├── deno.jsonc ├── README.md ├── LICENSE └── doc └── ddc-filter-converter_remove_overlap.txt /denops/@ddc-filters/converter_remove_overlap/deno.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@shougo/ddc-filter-converter_remove_overlap", 3 | "exports": { 4 | ".": "./main.ts" 5 | }, 6 | "publish": { 7 | "include": [ 8 | "**/*.ts" 9 | ] 10 | }, 11 | "imports": { 12 | "@shougo/ddc-vim": "jsr:@shougo/ddc-vim@~10.0.0", 13 | "@denops/std": "jsr:@denops/std@~8.0.0", 14 | "@std/assert": "jsr:@std/assert@~1.0.3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /deno.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "lock": false, 3 | "tasks": { 4 | "cache": "deno install --reload", 5 | "check": "deno check denops/**/*.ts", 6 | "fmt": "deno fmt denops", 7 | "lint": "deno lint denops", 8 | "lint-fix": "deno lint --fix denops", 9 | "test": "deno test -A --doc --parallel --shuffle denops/**/*.ts", 10 | "test:publish": "deno publish --dry-run --allow-dirty --set-version 0.0.0", 11 | "update": "deno outdated --recursive", 12 | "upgrade": "deno outdated --recursive --update" 13 | }, 14 | "workspace": [ 15 | "./denops/@ddc-filters/converter_remove_overlap" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ddc-filter-converter_remove_overlap 2 | 3 | Removes overlapped text for ddc.vim 4 | 5 | The filter removes overlapped text in a candidate's word. 6 | 7 | For example if you want to complete "foobar" before "bar", only "foo" is 8 | inserted. Because "bar" is already inserted in the text. It is useful if you 9 | want to replace texts. 10 | 11 | ## Required 12 | 13 | ### denops.vim 14 | 15 | https://github.com/vim-denops/denops.vim 16 | 17 | ### ddc.vim 18 | 19 | https://github.com/Shougo/ddc.vim 20 | 21 | ## Configuration 22 | 23 | ```vim 24 | call ddc#custom#patch_global('sourceOptions', #{ 25 | \ _: #{ 26 | \ converters: ['converter_remove_overlap'], 27 | \ }) 28 | ``` 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT license 2 | 3 | Copyright (c) Shougo Matsushita 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /doc/ddc-filter-converter_remove_overlap.txt: -------------------------------------------------------------------------------- 1 | *ddc-filter-converter_remove_overlap.txt* 2 | Remove overlapped text converter for ddc.vim 3 | 4 | Author: Shougo 5 | License: MIT license 6 | 7 | CONTENTS *ddc-filter-converter_remove_overlap-contents* 8 | 9 | Introduction |ddc-filter-converter_remove_overlap-introduction| 10 | Install |ddc-filter-converter_remove_overlap-install| 11 | Examples |ddc-filter-converter_remove_overlap-examples| 12 | Params |ddc-filter-converter_remove_overlap-params| 13 | 14 | 15 | ============================================================================== 16 | INTRODUCTION *ddc-filter-converter_remove_overlap-introduction* 17 | 18 | It is matched rank order sorter. The higher the head matched word or already 19 | typed or inserted word. 20 | 21 | For example if you want to complete "foobar" before "bar", only "foo" is 22 | inserted. Because "bar" is already inserted in the text. 23 | It is useful if you want to replace texts. 24 | 25 | ============================================================================== 26 | INSTALL *ddc-filter-converter_remove_overlap-install* 27 | 28 | Please install both "ddc.vim" and "denops.vim". 29 | 30 | https://github.com/Shougo/ddc.vim 31 | https://github.com/vim-denops/denops.vim 32 | 33 | 34 | ============================================================================== 35 | EXAMPLES *ddc-filter-converter_remove_overlap-examples* 36 | > 37 | call ddc#custom#patch_global('sourceOptions', #{ 38 | \ _: #{ 39 | \ converters: ['converter_remove_overlap'], 40 | \ } 41 | \ }) 42 | < 43 | 44 | ============================================================================== 45 | PARAMS *ddc-filter-converter_remove_overlap-params* 46 | 47 | ============================================================================== 48 | vim:tw=78:ts=8:ft=help:norl:noet:fen:noet: 49 | -------------------------------------------------------------------------------- /denops/@ddc-filters/converter_remove_overlap/main.ts: -------------------------------------------------------------------------------- 1 | import { type Context, type Item } from "@shougo/ddc-vim/types"; 2 | import { BaseFilter } from "@shougo/ddc-vim/filter"; 3 | 4 | import type { Denops } from "@denops/std"; 5 | import * as fn from "@denops/std/function"; 6 | 7 | import { assertEquals } from "@std/assert/equals"; 8 | 9 | function overlapLength(left: string, nextInputWords: string[]): number { 10 | let pos = nextInputWords.length; 11 | while (pos > 0 && !left.endsWith(nextInputWords.slice(0, pos).join(""))) { 12 | pos -= 1; 13 | } 14 | return nextInputWords.slice(0, pos).join("").length; 15 | } 16 | 17 | type Params = Record; 18 | 19 | export class Filter extends BaseFilter { 20 | override async filter(args: { 21 | denops: Denops; 22 | context: Context; 23 | completeStr: string; 24 | items: Item[]; 25 | }): Promise { 26 | if (args.context.nextInput == "") { 27 | return args.items; 28 | } 29 | 30 | const nextInputWords = args.context.nextInput.split(/([a-zA-Z_]\w*|\W)/) 31 | .filter(( 32 | v, 33 | ) => v != ""); 34 | 35 | if (nextInputWords.length === 0) { 36 | return args.items; 37 | } 38 | 39 | // Skip parentheses if close parentheses is found after cursor. 40 | const curPos = (await fn.getcurpos(args.denops)).slice(1, 3) as number[]; 41 | const checkPairs = []; 42 | 43 | async function searchPairs(begin: string, end: string): Promise { 44 | const pairPos = (await fn.searchpairpos( 45 | args.denops, 46 | begin, 47 | "", 48 | end, 49 | "nW", 50 | "", 51 | await fn.line(args.denops, "."), 52 | )) as number[]; 53 | return args.context.input.includes(begin) && curPos < pairPos && 54 | curPos[0] == pairPos[0]; 55 | } 56 | if (await searchPairs("(", ")")) { 57 | checkPairs.push(["(", ")"]); 58 | } 59 | if (await searchPairs("[", "]")) { 60 | checkPairs.push(["[", "]"]); 61 | } 62 | 63 | for (const item of args.items) { 64 | const word = item.word; 65 | const overlap = overlapLength(word, nextInputWords); 66 | 67 | // Check parentheses 68 | let skip = false; 69 | for (const pair of checkPairs) { 70 | if ( 71 | overlap > 0 && 72 | word.includes(pair[0]) && 73 | word.slice(0, -overlap).includes(pair[1]) 74 | ) { 75 | skip = true; 76 | break; 77 | } 78 | } 79 | if (skip || overlap == 0) { 80 | continue; 81 | } 82 | 83 | if (!("abbr" in item)) { 84 | item.abbr = word; 85 | } 86 | item.word = word.slice(0, -overlap); 87 | } 88 | 89 | return args.items; 90 | } 91 | 92 | override params(): Params { 93 | return {}; 94 | } 95 | } 96 | 97 | Deno.test("overlapLength", () => { 98 | assertEquals(overlapLength("date", ["te"]), 2); 99 | }); 100 | --------------------------------------------------------------------------------