Skip to content
This repository has been archived by the owner on Apr 1, 2020. It is now read-only.

Commit

Permalink
Feature/buffers menu (#1334)
Browse files Browse the repository at this point in the history
* add buffer menu plugin
add inactive buffers to buffer manager
add inactive buffer class which is distinct from buffer class
add icon class for file fn for menu icons

* prettify buffers-menu index
experiment with command to delete buffer

* add indicator for current and tweak styles to menu nowrap

* recreate inactive buffers on enter and remove max-width

* rename addInactiveBuffers to populateBuffers
use this as buffer source as bufbyId is inaccurate

* truncate filenames

* remove unnecessary loading false call

* register different buffer open commands

* add proxies to handle incorrect input for file open
add buffer delete command

* add extra check in item selected to ensure menu item

* use inactive buffer from oni type

* fix openBuffers to work with OniEditor

* use already defined buffer delete command in oniEditor

* re-add new oni api

* fix keybindings typo

* add filter to bufferlist commands

* [WIP] add filter for menu commands - need to update oni-api

* update oni-api version

* add fixme comment to match filepath accurately

* Remove bufDelete function for now as event is noop

* fix buffer delete command add new event hooks

* fix metadata removal
add buffer navigation following deletion
rename commands

* fix default binding to use new command name
fix comment typo
  • Loading branch information
akinsho authored and bryphe committed Jan 27, 2018
1 parent ea44c69 commit 0fc0f43
Show file tree
Hide file tree
Showing 17 changed files with 303 additions and 21 deletions.
14 changes: 8 additions & 6 deletions .oni/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// check out our wiki page:
// https://github.com/onivim/oni/wiki/Configuration

const activate = (oni) => {
const activate = oni => {
console.log("Oni config activated")
}

Expand All @@ -13,9 +13,11 @@ const deactivate = () => {
module.exports = {
activate,
deactivate,
"workspace.testFileMappings": [{
sourceFolder: "browser/src",
mappedFolder: "browser/test",
mappedFileName: "${fileName}Tests.ts",
}]
"workspace.testFileMappings": [
{
sourceFolder: "browser/src",
mappedFolder: "browser/test",
mappedFileName: "${fileName}Tests.ts",
},
],
}
64 changes: 63 additions & 1 deletion browser/src/Editor/BufferManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import "rxjs/add/operator/concatMap"

import * as Oni from "oni-api"

import { EventContext, NeovimInstance } from "./../neovim"
import {
BufferEventContext,
EventContext,
InactiveBufferContext,
NeovimInstance,
} from "./../neovim"
import * as LanguageManager from "./../Services/Language"
import { PromiseQueue } from "./../Services/Language/PromiseQueue"

Expand Down Expand Up @@ -293,6 +298,7 @@ export class Buffer implements Oni.Buffer {
export class BufferManager {
private _idToBuffer: { [id: string]: Buffer } = {}
private _filePathToId: { [filePath: string]: string } = {}
private _bufferList: { [id: string]: InactiveBuffer } = {}

constructor(private _neovimInstance: NeovimInstance, private _actions: typeof Actions) {}

Expand All @@ -314,7 +320,63 @@ export class BufferManager {
return this._idToBuffer[id]
}

public populateBufferList(buffers: BufferEventContext): void {
const bufferlist = buffers.existingBuffers.reduce((list, buffer) => {
const id = `${buffer.bufferNumber}`
if (buffer.bufferFullPath) {
this._filePathToId[buffer.bufferFullPath] = id
list[id] = new InactiveBuffer(buffer)
}
return list
}, {})
const currentId = buffers.current.bufferNumber.toString()
const current = this.getBufferById(currentId)
this._bufferList = { ...bufferlist, [currentId]: current }
}

public getBufferById(id: string): Buffer {
return this._idToBuffer[id]
}

public getBuffers(): Array<Buffer | InactiveBuffer> {
return Object.values(this._bufferList)
}
}

export class InactiveBuffer implements Oni.InactiveBuffer {
private _id: string
private _filePath: string
private _language: string
private _version: number
private _modified: boolean
private _lineCount: number

public get id(): string {
return this._id
}

public get filePath(): string {
return this._filePath
}
public get language(): string {
return this._language
}
public get version(): number {
return this._version
}
public get modified(): boolean {
return this._modified
}
public get lineCount(): number {
return this._lineCount
}

constructor(inactiveBuffer: InactiveBufferContext) {
this._id = `${inactiveBuffer.bufferNumber}`
this._filePath = inactiveBuffer.bufferFullPath
this._language = inactiveBuffer.filetype
this._version = inactiveBuffer.version || null
this._modified = inactiveBuffer.modified || false
this._lineCount = null
}
}
54 changes: 52 additions & 2 deletions browser/src/Editor/NeovimEditor/NeovimEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,14 @@ export class NeovimEditor extends Editor implements IEditor {
this._bufferManager.updateBufferFromEvent(current)
})

this._neovimInstance.autoCommands.onBufDelete.subscribe((evt: BufferEventContext) =>
this._onBufDelete(evt),
)

this._neovimInstance.autoCommands.onBufUnload.subscribe((evt: BufferEventContext) =>
this._onBufUnload(evt),
)

this._neovimInstance.autoCommands.onBufEnter.subscribe((evt: BufferEventContext) =>
this._onBufEnter(evt),
)
Expand Down Expand Up @@ -645,8 +653,21 @@ export class NeovimEditor extends Editor implements IEditor {
await this._neovimInstance.request("nvim_call_atomic", [atomicCalls])
}

public async openFile(file: string): Promise<Oni.Buffer> {
await this._neovimInstance.command(":e " + file)
public async openFile(file: string, method = "edit"): Promise<Oni.Buffer> {
const cmd = new Proxy(
{
tab: "taball!",
horizontal: "sp!",
vertical: "vsp!",
edit: "e!",
},
{
get: (target: { [cmd: string]: string }, name: string) =>
name in target ? target[name] : "e!",
},
)

await this._neovimInstance.command(`:${cmd[method]} ${file}`)
return this.activeBuffer
}

Expand Down Expand Up @@ -709,6 +730,23 @@ export class NeovimEditor extends Editor implements IEditor {
this._scheduleRender()
}

public getBuffers(): Array<Oni.Buffer | Oni.InactiveBuffer> {
return this._bufferManager.getBuffers()
}

public async bufferDelete(bufferId: string = this.activeBuffer.id): Promise<void> {
// FIXME: currently this command forces a bufEnter event by navigating away
// from the closed buffer which is currently the only means of updating Oni
// post a BufDelete event
await this._neovimInstance.command(`bd ${bufferId}`)
if (bufferId === "%" || bufferId === this.activeBuffer.id) {
await this._neovimInstance.command(`bnext`)
} else {
await this._neovimInstance.command(`bnext`)
await this._neovimInstance.command(`bprev`)
}
}

public render(): JSX.Element {
const onBufferClose = (bufferId: number) => {
this._neovimInstance.command(`bw! ${bufferId}`)
Expand Down Expand Up @@ -818,6 +856,7 @@ export class NeovimEditor extends Editor implements IEditor {

private async _onBufEnter(evt: BufferEventContext): Promise<void> {
const buf = this._bufferManager.updateBufferFromEvent(evt.current)
this._bufferManager.populateBufferList(evt)

const lastBuffer = this.activeBuffer
if (lastBuffer && lastBuffer.filePath !== buf.filePath) {
Expand Down Expand Up @@ -858,7 +897,18 @@ export class NeovimEditor extends Editor implements IEditor {
})
}

private async _onBufUnload(evt: BufferEventContext): Promise<void> {
this._bufferManager.populateBufferList(evt)
this._neovimInstance.getBufferIds().then(ids => this._actions.setCurrentBuffers(ids))
}

private async _onBufDelete(evt: BufferEventContext): Promise<void> {
this._bufferManager.populateBufferList(evt)
this._neovimInstance.getBufferIds().then(ids => this._actions.setCurrentBuffers(ids))
}

private async _onBufWipeout(evt: BufferEventContext): Promise<void> {
this._bufferManager.populateBufferList(evt)
this._neovimInstance.getBufferIds().then(ids => this._actions.setCurrentBuffers(ids))
}

Expand Down
12 changes: 10 additions & 2 deletions browser/src/Editor/OniEditor/OniEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ export class OniEditor implements IEditor {
this._neovimEditor.leave()
}

public async openFile(file: string): Promise<Oni.Buffer> {
return this._neovimEditor.openFile(file)
public async openFile(file: string, method = "edit"): Promise<Oni.Buffer> {
return this._neovimEditor.openFile(file, method)
}

public async newFile(filePath: string): Promise<Oni.Buffer> {
Expand All @@ -168,6 +168,14 @@ export class OniEditor implements IEditor {
this._neovimEditor.executeCommand(command)
}

public getBuffers(): Array<Oni.Buffer | Oni.InactiveBuffer> {
return this._neovimEditor.getBuffers()
}

public async bufferDelete(bufferId: string = this.activeBuffer.id): Promise<void> {
this._neovimEditor.bufferDelete(bufferId)
}

public async init(filesToOpen: string[]): Promise<void> {
Log.info("[OniEditor::init] Called with filesToOpen: " + filesToOpen)

Expand Down
4 changes: 3 additions & 1 deletion browser/src/Input/KeyBindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const applyDefaultKeyBindings = (oni: Oni.Plugin.Api, config: Configurati
input.bind("<s-m-t>", "language.symbols.document")
input.bind("<m-m>", "oni.editor.minimize")
input.bind("<m-h>", "oni.editor.hide")
input.bind("<c-tab>", "buffer.toggle")

if (config.getValue("editor.clipboard.enabled")) {
input.bind("<m-c>", "editor.clipboard.yank", isVisualMode)
Expand All @@ -48,6 +49,7 @@ export const applyDefaultKeyBindings = (oni: Oni.Plugin.Api, config: Configurati
input.bind("<a-enter>", "language.codeAction.expand")
input.bind("<c-t>", "language.symbols.workspace", () => !menu.isMenuOpen())
input.bind("<s-c-t>", "language.symbols.document")
input.bind("<c-tab>", "buffer.toggle")

if (config.getValue("editor.clipboard.enabled")) {
input.bind("<c-c>", "editor.clipboard.yank", isVisualMode)
Expand All @@ -74,7 +76,7 @@ export const applyDefaultKeyBindings = (oni: Oni.Plugin.Api, config: Configurati
input.bind(
["<s-enter>", "<s-f12>"],
"language.gotoDefinition.openHorizontal",
() => isNormalMode() && !menu.IsMenuOpen(),
() => isNormalMode() && !menu.isMenuOpen(),
)
input.bind("<S-C-P>", "commands.show", isNormalMode)
input.bind("<C-pageup>", "oni.process.cyclePrevious")
Expand Down
6 changes: 6 additions & 0 deletions browser/src/Plugins/Api/Ui.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getInstance } from "../../Services/IconThemes"
import { Icon, IconProps, IconSize } from "../../UI/Icon"

export class Ui {
Expand All @@ -7,6 +8,11 @@ export class Ui {
return this._react.createElement(Icon, props)
}

public getIconClassForFile(filename: string, language?: string): string {
const Icons = getInstance()
return Icons.getIconClassForFile(filename, language)
}

public get iconSize(): any {
return IconSize
}
Expand Down
6 changes: 3 additions & 3 deletions browser/src/Services/EditorManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ class AllEditors implements Oni.Editor {
return this._activeEditor.neovim
}

public openFile(file: string): Promise<Oni.Buffer> {
Log.warn("Not implemented")
return Promise.resolve(null)
public async openFile(file: string, method = "edit"): Promise<Oni.Buffer> {
await this._activeEditor.openFile(file, method)
return this._activeEditor.activeBuffer
}

public openFiles(files: string[]): Promise<Oni.Buffer[]> {
Expand Down
2 changes: 2 additions & 0 deletions browser/src/Services/Menu/Menu.less
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@
-webkit-user-drag: none;
cursor: pointer;
font-size: @font-size-normal;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

.fa:not(.fa-spin) {
padding-right: 8px;
Expand Down
2 changes: 1 addition & 1 deletion browser/src/Services/Menu/Menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export class MenuManager {
}
}

export class Menu {
export class Menu implements Oni.Menu.MenuInstance {
private _onItemSelected = new Event<any>()
private _onSelectedItemChanged = new Event<Oni.Menu.MenuOption>()
private _onFilterTextChanged = new Event<string>()
Expand Down
2 changes: 2 additions & 0 deletions browser/src/Services/Menu/MenuFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const fuseFilter = (
detail: o.detail,
icon: o.icon,
pinned: o.pinned,
metadata: o.metadata,
detailHighlights: [],
labelHighlights: [],
}
Expand Down Expand Up @@ -119,6 +120,7 @@ export const fuseFilter = (
pinned: f.item.pinned,
label: f.item.label,
detail: f.item.detail,
metadata: f.item.metadata,
labelHighlights: convertArrayOfPairsToIndices(labelHighlights),
detailHighlights: convertArrayOfPairsToIndices(detailHighlights),
}
Expand Down
14 changes: 14 additions & 0 deletions browser/src/neovim/NeovimAutoCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export interface INeovimAutoCommands {
onBufEnter: IEvent<BufferEventContext>
onBufWipeout: IEvent<BufferEventContext>
onBufWinEnter: IEvent<EventContext>
onBufDelete: IEvent<BufferEventContext>
onBufUnload: IEvent<BufferEventContext>
onBufWritePost: IEvent<EventContext>
onWinEnter: IEvent<EventContext>
onCursorMoved: IEvent<EventContext>
Expand All @@ -30,6 +32,8 @@ export class NeovimAutoCommands {
private _onBufEnterEvent = new Event<BufferEventContext>()
private _onBufWritePostEvent = new Event<EventContext>()
private _onBufWipeoutEvent = new Event<BufferEventContext>()
private _onBufDeleteEvent = new Event<BufferEventContext>()
private _onBufUnloadEvent = new Event<BufferEventContext>()
private _onBufWinEnterEvent = new Event<EventContext>()
private _onFileTypeChangedEvent = new Event<EventContext>()
private _onWinEnterEvent = new Event<EventContext>()
Expand All @@ -41,6 +45,14 @@ export class NeovimAutoCommands {
return this._onBufEnterEvent
}

public get onBufDelete(): IEvent<BufferEventContext> {
return this._onBufDeleteEvent
}

public get onBufUnload(): IEvent<BufferEventContext> {
return this._onBufUnloadEvent
}

public get onBufWritePost(): IEvent<EventContext> {
return this._onBufWritePostEvent
}
Expand Down Expand Up @@ -79,6 +91,8 @@ export class NeovimAutoCommands {
BufWritePost: this._onBufWritePostEvent,
BufWinEnter: this._onBufWinEnterEvent,
BufWipeout: this._onBufWipeoutEvent,
BufUnload: this._onBufUnloadEvent,
BufDelete: this._onBufDeleteEvent,
CursorMoved: this._onCursorMovedEvent,
CursorMovedI: this._onCursorMovedIEvent,
FileType: this._onFileTypeChangedEvent,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
"minimist": "1.2.0",
"msgpack-lite": "0.1.26",
"ocaml-language-server": "1.0.12",
"oni-api": "0.0.24",
"oni-api": "^0.0.26",
"oni-neovim-binaries": "0.1.0",
"oni-ripgrep": "0.0.3",
"oni-types": "0.0.4",
Expand Down
8 changes: 7 additions & 1 deletion vim/core/oni-core-interop/plugin/init.vim
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,13 @@ function OniNotifyEvent(eventName)
call OniNotify(["event", a:eventName, context])
endfunction


function! s:filter_buffer(i)
return bufexists(a:i) && buflisted(a:i) && "quickfix" !=? getbufvar(a:i, "&buftype")
endfunction

function User_buffers() " help buffers are always unlisted, but quickfix buffers are not
return filter(range(1,bufnr('$')),'buflisted(v:val) && "quickfix" !=? getbufvar(v:val, "&buftype")')
return filter(range(1,bufnr('$')),'s:filter_buffer(v:val)')
endfunction

function OniGetAllBuffers()
Expand Down Expand Up @@ -131,6 +136,7 @@ augroup OniEventListeners
autocmd! FileType * :call OniNotifyEvent("FileType")
autocmd! WinEnter * :call OniNotifyEvent("WinEnter")
autocmd! BufDelete * :call OniNotifyWithBuffers("BufDelete")
autocmd! BufUnload * :call OniNotifyWithBuffers("BufUnload")
autocmd! BufWipeout * :call OniNotifyWithBuffers("BufWipeout")
autocmd! CursorMoved * :call OniNotifyEvent("CursorMoved")
autocmd! CursorMovedI * :call OniNotifyEvent("CursorMovedI")
Expand Down
Loading

0 comments on commit 0fc0f43

Please sign in to comment.