├── LICENSE ├── README.md ├── denops └── @ddc-filters │ └── sorter_rank.ts └── doc └── ddc-filter-sorter_rank.txt /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ddc-filter-sorter_rank 2 | 3 | Matched rank order sorter for ddc.vim 4 | 5 | It is matched rank order sorter. The higher the head matched word or already 6 | typed or inserted word. 7 | 8 | ## Required 9 | 10 | ### denops.vim 11 | 12 | https://github.com/vim-denops/denops.vim 13 | 14 | ### ddc.vim 15 | 16 | https://github.com/Shougo/ddc.vim 17 | 18 | ## Configuration 19 | 20 | ```vim 21 | call ddc#custom#patch_global('sourceOptions', #{ 22 | \ _: #{ 23 | \ sorters: ['sorter_rank'], 24 | \ } 25 | \ }) 26 | ``` 27 | -------------------------------------------------------------------------------- /denops/@ddc-filters/sorter_rank.ts: -------------------------------------------------------------------------------- 1 | import { type DdcOptions, type Item } from "jsr:@shougo/ddc-vim@~9.1.0/types"; 2 | import { BaseFilter } from "jsr:@shougo/ddc-vim@~9.1.0/filter"; 3 | import { convertKeywordPattern } from "jsr:@shougo/ddc-vim@~9.1.0/utils"; 4 | 5 | import type { Denops } from "jsr:@denops/core@~7.0.0"; 6 | import * as fn from "jsr:@denops/std@~7.4.0/function"; 7 | 8 | import { assertEquals } from "jsr:@std/assert@~1.0.3/equals"; 9 | 10 | function calcScore( 11 | str: string, 12 | completeStr: string, 13 | cache: Record, 14 | linenr: number, 15 | ): number { 16 | let score = 0; 17 | if (str.indexOf(completeStr) == 0) { 18 | score += 200; 19 | } else if (str.toLowerCase().indexOf(completeStr.toLowerCase()) == 0) { 20 | score += 60; 21 | } else if (str.toLowerCase().indexOf(completeStr.toLowerCase()) > 0) { 22 | score += 20; 23 | } 24 | score -= str.length * 2; 25 | 26 | if (str in cache) { 27 | score += LINES_MAX - Math.abs(cache[str] - linenr); 28 | } 29 | return score; 30 | } 31 | 32 | const LINES_MAX = 150; 33 | const COLUMNS_MAX = 150; 34 | 35 | type Params = Record; 36 | 37 | export class Filter extends BaseFilter { 38 | override events = ["InsertEnter"] as never[]; 39 | 40 | _cache: Record = {}; 41 | 42 | override async onEvent(args: { 43 | denops: Denops; 44 | options: DdcOptions; 45 | }): Promise { 46 | const maxSize = LINES_MAX; 47 | const currentLine = (await args.denops.call("line", ".")) as number; 48 | const minLines = Math.max(1, currentLine - maxSize); 49 | const maxLines = Math.min( 50 | await fn.line(args.denops, "$"), 51 | currentLine + maxSize, 52 | ); 53 | 54 | // Convert keywordPattern 55 | const keywordPattern = await convertKeywordPattern( 56 | args.denops, 57 | "\\k*", 58 | ); 59 | 60 | this._cache = {}; 61 | let linenr = minLines; 62 | const pattern = new RegExp(keywordPattern, "gu"); 63 | for (const line of await fn.getline(args.denops, minLines, maxLines)) { 64 | if (line.length > COLUMNS_MAX) { 65 | // Skip too long lines 66 | continue; 67 | } 68 | 69 | for (const match of line.matchAll(pattern)) { 70 | const word = match[0]; 71 | if ( 72 | word in this._cache && 73 | Math.abs(this._cache[word] - currentLine) <= 74 | Math.abs(linenr - currentLine) 75 | ) { 76 | continue; 77 | } 78 | this._cache[word] = linenr; 79 | } 80 | linenr += 1; 81 | } 82 | } 83 | 84 | override async filter(args: { 85 | denops: Denops; 86 | completeStr: string; 87 | items: Item[]; 88 | }): Promise { 89 | if (args.completeStr.length === 0) { 90 | return args.items; 91 | } 92 | 93 | const linenr = await fn.line(args.denops, "."); 94 | 95 | const scores: Record = {}; 96 | for (const item of args.items) { 97 | scores[item.word] = calcScore( 98 | item.word, 99 | args.completeStr, 100 | this._cache, 101 | linenr, 102 | ); 103 | } 104 | 105 | return Promise.resolve( 106 | args.items.sort((a, b) => scores[b.word] - scores[a.word]), 107 | ); 108 | } 109 | 110 | override params(): Params { 111 | return {}; 112 | } 113 | } 114 | 115 | Deno.test("calcScore", () => { 116 | assertEquals(calcScore("", "", {}, 0), 100); 117 | }); 118 | -------------------------------------------------------------------------------- /doc/ddc-filter-sorter_rank.txt: -------------------------------------------------------------------------------- 1 | *ddc-filter-sorter_rank.txt* Rank sorter for ddc.vim 2 | 3 | Author: Shougo 4 | License: MIT license 5 | 6 | CONTENTS *ddc-filter-sorter_rank-contents* 7 | 8 | Introduction |ddc-filter-sorter_rank-introduction| 9 | Install |ddc-filter-sorter_rank-install| 10 | Examples |ddc-filter-sorter_rank-examples| 11 | Params |ddc-filter-sorter_rank-params| 12 | 13 | 14 | ============================================================================== 15 | INTRODUCTION *ddc-filter-sorter_rank-introduction* 16 | 17 | It is matched rank order sorter. The higher is the head matched word or 18 | already typed or inserted word. 19 | 20 | 21 | ============================================================================== 22 | INSTALL *ddc-filter-sorter_rank-install* 23 | 24 | Please install both "ddc.vim" and "denops.vim". 25 | 26 | https://github.com/Shougo/ddc.vim 27 | https://github.com/vim-denops/denops.vim 28 | 29 | 30 | ============================================================================== 31 | EXAMPLES *ddc-filter-sorter_rank-examples* 32 | > 33 | call ddc#custom#patch_global('sourceOptions', #{ 34 | \ _: #{ 35 | \ sorters: ['sorter_rank'], 36 | \ } 37 | \ }) 38 | < 39 | 40 | ============================================================================== 41 | PARAMS *ddc-filter-sorter_rank-params* 42 | 43 | ============================================================================== 44 | vim:tw=78:ts=8:ft=help:norl:noet:fen:noet: 45 | --------------------------------------------------------------------------------