Skip to content

Commit

Permalink
fix(list): add highlight for vim
Browse files Browse the repository at this point in the history
  • Loading branch information
chemzqm committed Jan 23, 2019
1 parent 83a8243 commit 6d59234
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 92 deletions.
8 changes: 5 additions & 3 deletions autoload/coc/list.vim
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,11 @@ endfunction

function! coc#list#setlines(lines, append)
let total = line('$')
call append(line('$'), a:lines)
if !a:append
call deletebufline('%', 1, total)
if a:append
call append(line('$'), a:lines)
else
call append(0, a:lines)
call deletebufline('%', len(a:lines) + 1, '$')
endif
endfunction

Expand Down
4 changes: 2 additions & 2 deletions src/list/basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ export default abstract class BasicList implements IList, Disposable {
nvim.command('pclose', true)
nvim.call('coc#util#open_file', [`${mod} ${height}sp +${lnum}`, filepath], true)
let cmd = 'setl previewwindow winfixheight'
// TODO not use cursorline
if (lnum != 1) cmd += ' cursorline'
// TODO use signs
// if (lnum != 1) cmd += ' cursorline'
if (!workspace.getDocument(uri)) cmd += ' nobuflisted bufhidden=wipe'
nvim.command(cmd, true)
nvim.command('normal! zt', true)
Expand Down
36 changes: 17 additions & 19 deletions src/list/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,24 @@ import { Neovim, Window } from '@chemzqm/neovim'
import debounce from 'debounce'
import { Disposable } from 'vscode-languageserver-protocol'
import events from '../events'
import { IList, Matcher, ListOptions, ListAction, ListContext, ListItem, WorkspaceConfiguration } from '../types'
import { IList, ListAction, ListContext, ListItem, ListOptions, Matcher, WorkspaceConfiguration } from '../types'
import workspace from '../workspace'
import History from './history'
import Mappings from './mappings'
import Prompt from './prompt'
import LocationList from './source/location'
import SymbolsList from './source/symbols'
import OutlineList from './source/outline'
import CommandsList from './source/commands'
import ExtensionList from './source/extensions'
import DiagnosticsList from './source/diagnostics'
import ExtensionList from './source/extensions'
import LinksList from './source/links'
import SourcesList from './source/sources'
import ServicesList from './source/services'
import OutputList from './source/output'
import ListsList from './source/lists'
import LocationList from './source/location'
import OutlineList from './source/outline'
import OutputList from './source/output'
import ServicesList from './source/services'
import SourcesList from './source/sources'
import SymbolsList from './source/symbols'
import UI from './ui'
import Worker from './worker'
import { wait } from '../util'
const logger = require('../util/logger')('list-manager')

const mouseKeys = ['<LeftMouse>', '<LeftDrag>', '<LeftRelease>', '<2-LeftMouse>']
Expand Down Expand Up @@ -100,7 +99,7 @@ export class ListManager {
this.ui.onDidChange(async () => {
if (this.activated) {
this.updateStatus()
if (!workspace.isVim) {
if (workspace.isNvim) {
this.prompt.drawPrompt()
}
}
Expand Down Expand Up @@ -221,14 +220,14 @@ export class ListManager {
await Promise.resolve(action.execute(item, this.context))
}
}
if (action.name == 'preview') {
await this.ui.restoreWindow()
}
if (action.persist && action.name != 'preview') {
if (action.persist || action.name == 'preview') {
let { bufnr } = ui
let winnr = bufnr ? await nvim.call('bufwinnr', bufnr) : -1
if (winnr == -1) return
await this.nvim.command(`${winnr}wincmd w`)
nvim.pauseNotification()
this.nvim.command(`${winnr}wincmd w`, true)
this.ui.restoreWindow()
await nvim.resumeNotification()
if (action.reload) await this.worker.loadItems(true)
}
} catch (e) {
Expand Down Expand Up @@ -274,10 +273,7 @@ export class ListManager {
nvim.command('echo ""', true)
if (close) ui.hide()
nvim.command('redraw', true)
if (workspace.isVim) {
await nvim.call('coc#list#restore', [])
await wait(100)
}
nvim.call('coc#list#restore', [], true)
await nvim.resumeNotification()
}

Expand Down Expand Up @@ -409,8 +405,10 @@ export class ListManager {
total: this.worker.length,
cwd: this.cwd,
}
nvim.pauseNotification()
buf.setVar('list_status', status, true)
if (ui.window) nvim.command('redraws', true)
nvim.resumeNotification()
}

private buildStatusline(): string {
Expand Down
17 changes: 3 additions & 14 deletions src/list/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Emitter, Event } from 'vscode-languageserver-protocol'
import workspace from '../workspace'
import { ListMode } from '../types'
import { Neovim } from '@chemzqm/neovim'
import { wait } from '../util'
const logger = require('../util/logger')('list-prompt')

export default class Prompt {
Expand Down Expand Up @@ -38,17 +37,7 @@ export default class Prompt {
public set mode(val: ListMode) {
if (val == this._mode) return
this._mode = val
if (workspace.isNvim) {
this.drawPrompt()
} else {
setTimeout(() => {
// Don't know why vim need redraws!
this.nvim.command('redraws!', true)
if (val == 'insert') {
this.drawPrompt()
}
}, 10)
}
this.drawPrompt()
}

public async start(input?: string, mode?: ListMode): Promise<void> {
Expand All @@ -73,7 +62,7 @@ export default class Prompt {

public drawPrompt(): void {
let { indicator, cusorIndex, input } = this
let cmds = workspace.isVim ? [] : ['echo ""']
let cmds = ['echo ""']
if (this.mode == 'insert') {
cmds.push(`echohl Special | echon '${indicator} ' | echohl None`)
if (cusorIndex == input.length) {
Expand All @@ -91,7 +80,7 @@ export default class Prompt {
}
if (workspace.isVim) cmds.push('redraw')
let cmd = cmds.join('|')
this.nvim.command(cmd)
this.nvim.command(cmd, true)
}

public moveLeft(): void {
Expand Down
101 changes: 57 additions & 44 deletions src/list/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,7 @@ export default class ListUI {
let maxHeight = config.get<number>('maxHeight', 12)
if (!(append && this.length > maxHeight)) {
let height = this.height = Math.max(1, Math.min(this.items.length, maxHeight))
if (workspace.isVim) {
nvim.command(`exe "normal! z${height}\\<CR>"`, true)
} else {
window.notify(`nvim_win_set_height`, [window, height])
}
window.notify(`nvim_win_set_height`, [window, height])
}
}
nvim.command('setl modifiable', true)
Expand All @@ -314,15 +310,10 @@ export default class ListUI {
await nvim.resumeNotification()
}

public async restoreWindow(): Promise<void> {
let { window, height, nvim } = this
public restoreWindow(): void {
let { window, height } = this
if (window && height) {
if (workspace.isVim) {
nvim.call('win_gotoid', window.id, true)
nvim.command(`exe "normal! z${height}\\<CR>"`, true)
} else {
await window.request(`nvim_win_set_height`, [window, height])
}
window.notify(`nvim_win_set_height`, [window, height])
}
}

Expand All @@ -347,49 +338,71 @@ export default class ListUI {
return this._bufnr ? workspace.nvim.createBuffer(this._bufnr) : null
}

private doAnsiHighlight(): void {
let { buffer, srcId, items } = this
let lnum = 0
for (let item of items) {
if (item.ansiHighlights && item.ansiHighlights.length) {
for (let hi of item.ansiHighlights) {
private doHighlight(): void {
if (workspace.isVim) {
this.doHighlightVim()
} else {
this.doHighlightNvim()
}
}

private doHighlightVim(): void {
let { nvim } = workspace
let { highlights, window, items } = this
nvim.call('win_gotoid', window.id, true)
nvim.call('clearmatches', [], true)
for (let i = 0; i < items.length; i++) {
let { ansiHighlights } = items[i]
let highlight = highlights[i]
if (ansiHighlights) {
for (let hi of ansiHighlights) {
let { span, hlGroup } = hi
buffer.addHighlight({
hlGroup,
srcId,
line: lnum,
colStart: span[0],
colEnd: span[1]
})
nvim.call('matchaddpos', [hlGroup, [[i + 1, span[0] + 1, span[1] - span[0]]], 99], true)
}
}
if (highlight) {
let { spans, hlGroup } = highlight
for (let span of spans) {
nvim.call('matchaddpos', [hlGroup || 'Search', [[i + 1, span[0] + 1, span[1] - span[0]]], 99], true)
}
}
lnum = lnum + 1
}
}

private doHighlight(): void {
if (workspace.isVim) return
private doHighlightNvim(): void {
let { nvim } = workspace
let { highlights, buffer, srcId, length } = this
let { highlights, buffer, items, srcId } = this
if (nvim.hasFunction('nvim_create_namespace')) {
buffer.clearNamespace(srcId)
} else {
buffer.clearHighlight({ srcId })
}
this.doAnsiHighlight()
if (!highlights.length) return
for (let highlight of highlights) {
if (highlight == null) continue
let { lnum, spans, hlGroup } = highlight
if (lnum >= length) continue
for (let span of spans) {
buffer.addHighlight({
hlGroup: hlGroup || 'Search',
srcId,
line: lnum,
colStart: span[0],
colEnd: span[1]
})
for (let i = 0; i < items.length; i++) {
let { ansiHighlights } = items[i]
let highlight = highlights[i]
if (ansiHighlights) {
for (let hi of ansiHighlights) {
let { span, hlGroup } = hi
buffer.addHighlight({
hlGroup,
srcId,
line: i,
colStart: span[0],
colEnd: span[1]
})
}
}
if (highlight) {
let { spans, hlGroup } = highlight
for (let span of spans) {
buffer.addHighlight({
hlGroup: hlGroup || 'Search',
srcId,
line: i,
colStart: span[0],
colEnd: span[1]
})
}
}
}
}
Expand Down
16 changes: 7 additions & 9 deletions src/list/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export default class Worker {
arr = res.items
highlights = res.highlights
} else {
highlights = this.getItemsHighlight(arr, count)
highlights = this.getItemsHighlight(arr)
}
count = count + remain.length
this._onDidChangeItems.fire({ items: arr, highlights, append: true })
Expand Down Expand Up @@ -228,14 +228,14 @@ export default class Worker {
return this.manager.prompt.input
}

private getItemsHighlight(items: ListItem[], lnum = 0): ListHighlights[] {
private getItemsHighlight(items: ListItem[]): ListHighlights[] {
let { input } = this
if (!input) return []
return items.map((item, i) => {
return items.map(item => {
let filterLabel = getFilterLabel(item)
let res = getMatchResult(filterLabel, input)
if (!res || !res.score) return null
return this.getHighlights(filterLabel, lnum + i, res.matches)
return this.getHighlights(filterLabel, res.matches)
})
}

Expand Down Expand Up @@ -264,7 +264,6 @@ export default class Worker {
let idx = ignorecase ? filterLabel.toLocaleLowerCase().indexOf(input.toLowerCase()) : filterLabel.indexOf(input)
if (idx != -1) {
highlights.push({
lnum,
spans: [[byteIndex(filterLabel, idx), byteIndex(filterLabel, idx + input.length)]]
})
}
Expand All @@ -281,7 +280,6 @@ export default class Worker {
let ms = filterLabel.match(regex)
if (ms && ms.length) {
highlights.push({
lnum,
spans: [[byteIndex(filterLabel, ms.index), byteIndex(filterLabel, ms.index + ms[0].length)]]
})
}
Expand Down Expand Up @@ -312,7 +310,7 @@ export default class Worker {
if (lnum < maxLength) {
for (let item of arr) {
if (!item.matches) continue
let hi = this.getHighlights(item.filterLabel, lnum, item.matches)
let hi = this.getHighlights(item.filterLabel, item.matches)
highlights.push(hi)
if (lnum == maxLength) break
lnum++
Expand All @@ -327,7 +325,7 @@ export default class Worker {
}
}

private getHighlights(text: string, lnum: number, matches: number[]): ListHighlights {
private getHighlights(text: string, matches: number[]): ListHighlights {
let spans: [number, number][] = []
if (matches.length) {
let start = matches.shift()
Expand All @@ -346,7 +344,7 @@ export default class Worker {
}
spans.push([byteIndex(text, start), byteIndex(text, curr) + 1])
}
return { lnum, spans }
return { spans }
}

private async loadMruList(cwd: string): Promise<void> {
Expand Down
1 change: 0 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,6 @@ export interface ListItem {
}

export interface ListHighlights {
lnum: number
// column indexes
spans: [number, number][]
hlGroup?: string
Expand Down

0 comments on commit 6d59234

Please sign in to comment.