akiyosi.goneovim/editor/editor.go

840 lines
22 KiB
Go
Raw Normal View History

2017-11-09 02:11:05 +00:00
package editor
2017-03-14 01:52:44 +00:00
import (
"fmt"
2018-01-08 10:23:16 +00:00
"os"
"path/filepath"
2017-05-12 04:07:54 +01:00
"runtime"
2018-01-08 10:23:16 +00:00
"strconv"
2017-03-14 07:20:31 +00:00
"strings"
2017-06-02 10:41:28 +01:00
"sync"
2017-03-14 01:52:44 +00:00
2019-03-13 11:50:52 +09:00
frameless "github.com/akiyosi/goqtframelesswindow"
2018-06-10 14:25:17 +09:00
clipb "github.com/atotto/clipboard"
2018-01-08 10:23:16 +00:00
homedir "github.com/mitchellh/go-homedir"
2017-03-14 01:52:44 +00:00
"github.com/neovim/go-client/nvim"
2017-06-16 08:43:05 +01:00
"github.com/therecipe/qt/core"
2018-01-05 08:07:29 +00:00
"github.com/therecipe/qt/gui"
2017-06-06 02:42:11 +01:00
"github.com/therecipe/qt/widgets"
2017-03-14 01:52:44 +00:00
)
var editor *Editor
// Highlight is
type Highlight struct {
2019-05-23 23:30:54 +09:00
kind string
uiName string
hiName string
2017-03-14 01:52:44 +00:00
foreground *RGBA
background *RGBA
2018-05-12 22:48:15 +09:00
italic bool
2019-04-01 08:06:58 +09:00
bold bool
2019-05-27 14:20:31 +09:00
underline bool
undercurl bool
2017-03-14 01:52:44 +00:00
}
2019-06-09 18:41:28 +09:00
// Cell is
type Cell struct {
2017-06-16 16:28:31 +01:00
normalWidth bool
char string
highlight Highlight
2017-03-14 01:52:44 +00:00
}
2018-12-21 12:18:41 +09:00
// NotifyButton is
2018-08-16 19:31:36 +09:00
type NotifyButton struct {
action func()
text string
}
2018-12-27 21:03:21 +09:00
// ColorPalette is
2018-12-27 12:38:42 +09:00
type ColorPalette struct {
2018-12-31 16:43:04 +09:00
fg *RGBA
bg *RGBA
inactiveFg *RGBA
comment *RGBA
abyss *RGBA
matchFg *RGBA
selectedBg *RGBA
activityBarFg *RGBA
activityBarBg *RGBA
sideBarFg *RGBA
sideBarBg *RGBA
sideBarSelectedItemBg *RGBA
scrollBarFg *RGBA
scrollBarBg *RGBA
widgetFg *RGBA
widgetBg *RGBA
widgetInputArea *RGBA
minimapCurrentRegion *RGBA
2019-05-31 16:41:37 +09:00
windowSeparator *RGBA
2019-06-07 02:00:14 +09:00
indentGuide *RGBA
2018-12-27 12:38:42 +09:00
}
2018-12-21 12:18:41 +09:00
// Notify is
2018-08-16 19:31:36 +09:00
type Notify struct {
level NotifyLevel
period int
2018-08-16 19:31:36 +09:00
message string
buttons []*NotifyButton
}
2017-03-14 01:52:44 +00:00
// Editor is the editor
type Editor struct {
2018-08-16 19:31:36 +09:00
signal *editorSignal
2018-08-15 17:44:53 +09:00
version string
app *widgets.QApplication
2018-12-05 21:17:56 +09:00
activity *Activity
splitter *widgets.QSplitter
notifyStartPos *core.QPoint
notificationWidth int
notify chan *Notify
guiInit chan bool
doneGuiInit bool
2018-08-15 17:44:53 +09:00
2018-01-08 10:23:16 +00:00
workspaces []*Workspace
active int
nvim *nvim.Nvim
window *frameless.QFramelessWindow
2018-01-08 10:23:16 +00:00
wsWidget *widgets.QWidget
wsSide *WorkspaceSide
2018-06-19 23:18:49 +09:00
deinSide *DeinSide
2018-01-08 10:23:16 +00:00
2017-05-10 07:28:44 +01:00
statuslineHeight int
width int
height int
2018-11-08 18:10:12 +09:00
iconSize int
2017-05-10 07:28:44 +01:00
tablineHeight int
2018-01-08 10:23:16 +00:00
stop chan struct{}
stopOnce sync.Once
2018-01-05 08:07:29 +00:00
specialKeys map[core.Qt__Key]string
controlModifier core.Qt__KeyboardModifier
cmdModifier core.Qt__KeyboardModifier
shiftModifier core.Qt__KeyboardModifier
altModifier core.Qt__KeyboardModifier
metaModifier core.Qt__KeyboardModifier
keyControl core.Qt__Key
keyCmd core.Qt__Key
keyAlt core.Qt__Key
keyShift core.Qt__Key
2018-12-31 16:43:04 +09:00
config gonvimConfig
notifications []*Notification
2018-12-27 12:38:42 +09:00
isDisplayNotifications bool
2018-10-13 22:59:41 +09:00
2018-12-31 16:43:04 +09:00
isSetGuiColor bool
colors *ColorPalette
svgs map[string]*SvgXML
2017-06-16 08:43:05 +01:00
}
type editorSignal struct {
core.QObject
2018-08-15 17:44:53 +09:00
_ func() `signal:"notifySignal"`
2017-03-14 01:52:44 +00:00
}
func (hl *Highlight) copy() Highlight {
highlight := Highlight{}
if hl.foreground != nil {
highlight.foreground = hl.foreground.copy()
}
if hl.background != nil {
highlight.background = hl.background.copy()
}
2018-05-12 22:48:15 +09:00
highlight.bold = hl.bold
highlight.italic = hl.italic
2017-03-14 01:52:44 +00:00
return highlight
}
2017-06-06 02:42:11 +01:00
2017-11-09 02:11:05 +00:00
// InitEditor is
func InitEditor() {
2019-05-18 23:57:02 +05:30
if runtime.GOOS == "linux" {
exe, _ := os.Executable()
dir, _ := filepath.Split(exe)
2019-05-27 14:20:31 +09:00
_ = os.Setenv("LD_LIBRARY_PATH", dir+"lib")
_ = os.Setenv("QT_PLUGIN_PATH", dir+"plugins")
2019-05-18 23:57:02 +05:30
}
home, err := homedir.Dir()
if err != nil {
home = "~"
}
2018-01-05 08:07:29 +00:00
editor = &Editor{
2019-04-14 13:52:03 +09:00
version: "v0.3.5",
2018-11-29 00:53:20 +09:00
signal: NewEditorSignal(nil),
notify: make(chan *Notify, 10),
stop: make(chan struct{}),
guiInit: make(chan bool, 1),
2018-12-31 16:43:04 +09:00
config: newGonvimConfig(home),
2017-06-06 02:42:11 +01:00
}
2018-01-05 08:07:29 +00:00
e := editor
2018-12-29 15:40:57 +09:00
e.app = widgets.NewQApplication(0, nil)
e.app.ConnectAboutToQuit(func() {
editor.cleanup()
})
2018-12-30 21:31:49 +09:00
e.app.SetFont(gui.NewQFont2(editor.config.Editor.FontFamily, editor.config.Editor.FontSize, 1, false), "QWidget")
e.app.SetFont(gui.NewQFont2(editor.config.Editor.FontFamily, editor.config.Editor.FontSize, 1, false), "QLabel")
2018-12-29 15:40:57 +09:00
2019-05-22 16:05:08 +09:00
// font := gui.NewQFontMetricsF(gui.NewQFont2(editor.config.Editor.FontFamily, int(editor.config.Editor.FontSize*23/25), 1, false))
2019-05-31 16:33:56 +09:00
e.iconSize = editor.config.Editor.FontSize * 11 / 9
2019-05-09 23:22:43 +09:00
e.initSVGS()
2018-12-29 17:31:44 +09:00
e.colors = initColorPalette()
e.colors.update()
2018-12-29 15:40:57 +09:00
2019-05-09 23:22:43 +09:00
e.initNotifications()
2019-03-02 21:40:40 +09:00
e.window = frameless.CreateQFramelessWindow(e.config.Editor.Transparent)
2018-12-29 15:40:57 +09:00
e.setWindowOptions()
2017-11-19 23:43:24 +09:00
2019-05-08 17:16:18 +09:00
layout := widgets.NewQBoxLayout(widgets.QBoxLayout__RightToLeft, nil)
2018-07-08 17:00:47 +09:00
layout.SetContentsMargins(0, 0, 0, 0)
layout.SetSpacing(0)
2018-05-06 14:49:45 +09:00
2019-05-14 12:56:46 +09:00
e.window.SetupContent(layout)
2018-01-05 08:07:29 +00:00
e.wsWidget = widgets.NewQWidget(nil, 0)
2018-06-20 23:34:11 +09:00
2019-01-29 18:04:31 +09:00
e.wsSide = newWorkspaceSide()
sideArea := widgets.NewQScrollArea(nil)
sideArea.SetWidgetResizable(true)
sideArea.SetVerticalScrollBarPolicy(core.Qt__ScrollBarAlwaysOff)
sideArea.ConnectEnterEvent(func(event *core.QEvent) {
sideArea.SetVerticalScrollBarPolicy(core.Qt__ScrollBarAsNeeded)
})
sideArea.ConnectLeaveEvent(func(event *core.QEvent) {
sideArea.SetVerticalScrollBarPolicy(core.Qt__ScrollBarAlwaysOff)
2019-01-29 18:04:31 +09:00
})
sideArea.SetFocusPolicy(core.Qt__ClickFocus)
sideArea.SetWidget(e.wsSide.widget)
sideArea.SetFrameShape(widgets.QFrame__NoFrame)
e.wsSide.scrollarea = sideArea
activityWidget := widgets.NewQWidget(nil, 0)
2019-05-31 19:13:27 +09:00
activityWidget.SetObjectName("Activity")
2019-01-29 18:04:31 +09:00
activityWidget.SetStyleSheet(" * { background-color: rgba(0, 0, 0, 0);}")
activity := newActivity()
activity.widget = activityWidget
activityWidget.SetLayout(activity.layout)
e.activity = activity
e.activity.sideArea.AddWidget(e.wsSide.scrollarea)
e.activity.sideArea.SetCurrentWidget(e.wsSide.scrollarea)
go e.dropShadow()
if e.config.ActivityBar.Visible == false {
e.activity.widget.Hide()
}
if e.config.SideBar.Visible == false {
e.activity.sideArea.Hide()
}
2019-01-29 18:04:31 +09:00
splitter := widgets.NewQSplitter2(core.Qt__Horizontal, nil)
2019-02-17 18:00:09 +09:00
splitter.SetStyleSheet(" * { background-color: rgba(0, 0, 0, 0);}")
2019-01-29 18:04:31 +09:00
splitter.AddWidget(e.activity.sideArea)
splitter.AddWidget(e.wsWidget)
splitter.SetSizes([]int{editor.config.SideBar.Width, editor.width - editor.config.SideBar.Width})
splitter.SetStretchFactor(1, 100)
splitter.SetObjectName("splitter")
e.splitter = splitter
2018-10-11 21:37:36 +09:00
e.workspaces = []*Workspace{}
sessionExists := false
if err == nil {
if e.config.Workspace.RestoreSession == true {
for i := 0; i < 20; i++ {
path := filepath.Join(home, ".gonvim", "sessions", strconv.Itoa(i)+".vim")
_, err := os.Stat(path)
if err != nil {
break
}
sessionExists = true
ws, err := newWorkspace(path)
if err != nil {
break
}
e.workspaces = append(e.workspaces, ws)
}
}
}
if !sessionExists {
ws, err := newWorkspace("")
if err != nil {
return
}
e.workspaces = append(e.workspaces, ws)
}
e.workspaceUpdate()
2019-05-29 00:09:39 +09:00
layout.AddWidget(splitter, 1, 0)
layout.AddWidget(e.activity.widget, 0, 0)
2019-02-01 20:31:46 +09:00
e.wsWidget.SetAttribute(core.Qt__WA_InputMethodEnabled, true)
e.wsWidget.ConnectInputMethodEvent(e.workspaces[e.active].InputMethodEvent)
e.wsWidget.ConnectInputMethodQuery(e.workspaces[e.active].InputMethodQuery)
2018-10-11 21:37:36 +09:00
2018-11-01 22:05:51 +09:00
e.wsWidget.ConnectResizeEvent(func(event *gui.QResizeEvent) {
for _, ws := range e.workspaces {
ws.updateSize()
}
})
// for macos, open file via Finder
2018-10-11 21:37:36 +09:00
macosArg := ""
if runtime.GOOS == "darwin" {
e.app.ConnectEvent(func(event *core.QEvent) bool {
switch event.Type() {
case core.QEvent__FileOpen:
2019-06-08 20:17:56 +09:00
// If gonvim not launched on finder (it is started in terminal)
if os.Getppid() != 1 {
return false
}
fileOpenEvent := gui.NewQFileOpenEventFromPointer(event.Pointer())
macosArg = fileOpenEvent.File()
2018-09-22 23:06:50 +09:00
gonvim := e.workspaces[e.active].nvim
2018-10-11 21:37:36 +09:00
isModified := ""
2018-09-22 23:06:50 +09:00
isModified, _ = gonvim.CommandOutput("echo &modified")
if isModified == "1" {
gonvim.Command(fmt.Sprintf(":tabe %s", macosArg))
} else {
gonvim.Command(fmt.Sprintf(":e %s", macosArg))
}
}
return true
})
2018-08-28 02:05:32 +09:00
e.window.ConnectCloseEvent(func(event *gui.QCloseEvent) {
e.app.DisconnectEvent()
event.Accept()
})
}
2018-01-05 08:07:29 +00:00
go func() {
2018-01-08 10:23:16 +00:00
<-editor.stop
2018-05-25 01:00:23 +09:00
if runtime.GOOS == "darwin" {
e.app.DisconnectEvent()
}
2018-01-05 08:07:29 +00:00
e.app.Quit()
}()
2019-05-14 13:04:49 +09:00
e.window.Show()
2018-01-17 10:03:54 +00:00
e.wsWidget.SetFocus2()
2018-01-05 08:07:29 +00:00
widgets.QApplication_Exec()
}
2018-12-29 17:31:44 +09:00
func (e *Editor) initNotifications() {
e.notifications = []*Notification{}
e.notificationWidth = editor.config.Editor.Width * 2 / 3
e.notifyStartPos = core.NewQPoint2(e.width-e.notificationWidth-10, e.height-30)
e.signal.ConnectNotifySignal(func() {
notify := <-e.notify
if notify.message == "" {
return
}
if notify.buttons == nil {
e.popupNotification(notify.level, notify.period, notify.message)
} else {
e.popupNotification(notify.level, notify.period, notify.message, notifyOptionArg(notify.buttons))
}
})
}
func (e *Editor) pushNotification(level NotifyLevel, p int, message string, opt ...NotifyOptionArg) {
2018-08-16 19:31:36 +09:00
opts := NotifyOptions{}
for _, o := range opt {
o(&opts)
}
n := &Notify{
level: level,
period: p,
2018-08-16 19:31:36 +09:00
message: message,
buttons: opts.buttons,
}
e.notify <- n
e.signal.NotifySignal()
}
func (e *Editor) popupNotification(level NotifyLevel, p int, message string, opt ...NotifyOptionArg) {
notification := newNotification(level, p, message, opt...)
2018-08-15 17:44:53 +09:00
notification.widget.SetParent(e.window)
notification.widget.AdjustSize()
x := e.notifyStartPos.X()
y := e.notifyStartPos.Y() - notification.widget.Height() - 4
2018-08-15 17:44:53 +09:00
notification.widget.Move2(x, y)
e.notifyStartPos = core.NewQPoint2(x, y)
e.notifications = append(e.notifications, notification)
2018-08-15 17:44:53 +09:00
notification.show()
}
2018-12-20 12:20:43 +09:00
func (e *Editor) dropShadow() {
// Drop shadow to Side Bar
if e.config.SideBar.DropShadow == true {
shadow := widgets.NewQGraphicsDropShadowEffect(nil)
shadow.SetBlurRadius(60)
shadow.SetColor(gui.NewQColor3(0, 0, 0, 35))
shadow.SetOffset3(6, 2)
e.activity.sideArea.SetGraphicsEffect(shadow)
}
// Drop shadow for Activity Bar
if e.config.ActivityBar.DropShadow == true {
shadow := widgets.NewQGraphicsDropShadowEffect(nil)
shadow.SetBlurRadius(60)
shadow.SetColor(gui.NewQColor3(0, 0, 0, 35))
shadow.SetOffset3(6, 2)
e.activity.widget.SetGraphicsEffect(shadow)
}
}
2018-12-27 21:03:21 +09:00
func initColorPalette() *ColorPalette {
2018-12-27 12:38:42 +09:00
rgbAccent := hexToRGBA(editor.config.SideBar.AccentColor)
2018-12-28 01:40:33 +09:00
fg := newRGBA(180, 185, 190, 1)
bg := newRGBA(9, 13, 17, 1)
2018-12-27 12:38:42 +09:00
return &ColorPalette{
2018-12-31 16:43:04 +09:00
bg: bg,
fg: fg,
2018-12-28 15:46:52 +09:00
selectedBg: bg.brend(rgbAccent, 0.3),
2018-12-31 16:43:04 +09:00
matchFg: rgbAccent,
2018-12-27 12:38:42 +09:00
}
}
2018-12-27 21:03:21 +09:00
func (c *ColorPalette) update() {
fg := c.fg
bg := c.bg
2018-12-28 15:46:52 +09:00
rgbAccent := hexToRGBA(editor.config.SideBar.AccentColor)
c.selectedBg = bg.brend(rgbAccent, 0.3)
2019-03-20 22:41:06 +09:00
c.inactiveFg = warpColor(bg, -80)
c.comment = warpColor(fg, -80)
2018-12-28 01:40:33 +09:00
c.abyss = warpColor(bg, 5)
2018-12-27 21:03:21 +09:00
c.activityBarFg = fg
2019-03-20 22:41:06 +09:00
c.activityBarBg = warpColor(bg, -10)
c.sideBarFg = warpColor(fg, -5)
c.sideBarBg = warpColor(bg, -5)
c.sideBarSelectedItemBg = warpColor(bg, -15)
c.scrollBarFg = warpColor(bg, -20)
2018-12-27 21:03:21 +09:00
c.scrollBarBg = bg
2019-03-20 22:41:06 +09:00
c.widgetFg = warpColor(fg, 5)
c.widgetBg = warpColor(bg, -10)
c.widgetInputArea = warpColor(bg, -30)
c.minimapCurrentRegion = warpColor(bg, 20)
2019-05-31 16:41:37 +09:00
c.windowSeparator = warpColor(bg, -40)
2019-06-07 02:00:14 +09:00
c.indentGuide = warpColor(bg, -2)
2018-12-27 21:03:21 +09:00
}
func (e *Editor) updateGUIColor() {
// if activity & sidebar is enabled
if e.activity != nil && e.wsSide != nil {
// for splitter
e.splitter.SetStyleSheet(" QSplitter::handle:horizontal { background-color: rgba(0, 0, 0, 0); }")
2018-12-27 21:03:21 +09:00
// for Activity Bar
2019-05-31 19:13:27 +09:00
e.activity.widget.SetStyleSheet(fmt.Sprintf("QWidget#Activity { background-color: rgba(0, 0, 0, 0); border-right: 1px solid %s}", editor.colors.windowSeparator.Hex()))
e.activity.sideArea.SetStyleSheet(fmt.Sprintf("* { background-color: rgba(0, 0, 0, 0); border-right: 1px solid %s}", editor.colors.windowSeparator.Hex()))
2018-12-27 21:03:21 +09:00
var svgEditContent string
if e.activity.editItem.active == true {
svgEditContent = e.getSvg("activityedit", e.colors.fg)
} else {
svgEditContent = e.getSvg("activityedit", e.colors.inactiveFg)
}
e.activity.editItem.icon.Load2(core.NewQByteArray2(svgEditContent, len(svgEditContent)))
var svgDeinContent string
if e.activity.deinItem.active == true {
svgDeinContent = e.getSvg("activitydein", e.colors.fg)
} else {
svgDeinContent = e.getSvg("activitydein", e.colors.inactiveFg)
}
e.activity.deinItem.icon.Load2(core.NewQByteArray2(svgDeinContent, len(svgDeinContent)))
e.wsSide.setColor()
2018-12-27 21:03:21 +09:00
}
2019-01-01 18:34:51 +09:00
e.workspaces[e.active].updateWorkspaceColor()
2018-12-28 01:40:33 +09:00
e.window.SetupWidgetColor((uint16)(e.colors.bg.R), (uint16)(e.colors.bg.G), (uint16)(e.colors.bg.B))
2019-05-14 12:32:00 +09:00
e.window.SetupTitleColor((uint16)(e.colors.fg.R), (uint16)(e.colors.fg.G), (uint16)(e.colors.fg.B))
2019-03-02 21:40:40 +09:00
2019-05-09 23:22:43 +09:00
// On linux, add a frame if alpha is 1.0
if runtime.GOOS == "linux" && e.config.Editor.Transparent == 1.0 {
2019-05-14 12:32:00 +09:00
e.window.Widget.SetStyleSheet(fmt.Sprintf(" * { background-color: rgba(%d, %d, %d, %f); }", e.colors.bg.R, e.colors.bg.G, e.colors.bg.B, e.config.Editor.Transparent))
e.window.TitleBar.Hide()
e.window.SetWindowFlag(core.Qt__FramelessWindowHint, false)
e.window.SetWindowFlag(core.Qt__NoDropShadowWindowHint, false)
e.window.Show()
2019-05-09 23:22:43 +09:00
}
2018-12-28 01:40:33 +09:00
e.window.SetWindowOpacity(1.0)
2018-12-27 21:03:21 +09:00
}
2018-06-24 13:36:41 +09:00
func hexToRGBA(hex string) *RGBA {
format := "#%02x%02x%02x"
if len(hex) == 4 {
format = "#%1x%1x%1x"
}
var r, g, b uint8
n, err := fmt.Sscanf(hex, format, &r, &g, &b)
if err != nil {
return nil
}
if n != 3 {
return nil
}
rgba := &RGBA{
R: (int)(r),
G: (int)(g),
B: (int)(b),
A: 1,
}
return rgba
}
func darkenHex(hex string) string {
c := hexToRGBA(hex)
d := shiftColor(c, 20)
return fmt.Sprintf("#%02x%02x%02x", (int)(d.R*255.0), (int)(d.G*255.0), (int)(d.B*255.0))
}
2018-08-08 23:02:24 +09:00
func shiftHex(hex string, v int) string {
c := hexToRGBA(hex)
d := shiftColor(c, v)
return fmt.Sprintf("#%02x%02x%02x", (int)(d.R*255.0), (int)(d.G*255.0), (int)(d.B*255.0))
}
2018-12-29 15:40:57 +09:00
func (e *Editor) setWindowOptions() {
2019-05-14 12:32:00 +09:00
e.window.SetupTitle("Gonvim")
e.window.SetupWidgetColor(0, 0, 0)
2018-12-29 17:31:44 +09:00
e.width = e.config.Editor.Width
e.height = e.config.Editor.Height
e.window.SetMinimumSize2(e.width, e.height)
2018-12-29 15:40:57 +09:00
e.window.SetWindowOpacity(0.0)
e.initSpecialKeys()
e.window.ConnectKeyPressEvent(e.keyPress)
e.window.SetAcceptDrops(true)
}
2018-04-19 21:07:48 +09:00
func isFileExist(filename string) bool {
2018-04-30 16:58:26 +09:00
_, err := os.Stat(filename)
return err == nil
2018-04-19 21:07:48 +09:00
}
2018-06-13 21:08:02 +09:00
func (e *Editor) copyClipBoard() {
go func() {
var yankedText string
2018-06-16 10:15:40 +09:00
yankedText, _ = e.workspaces[e.active].nvim.CommandOutput("echo getreg()")
2018-06-13 21:08:02 +09:00
if yankedText != "" {
clipb.WriteAll(yankedText)
}
}()
2018-06-16 10:15:40 +09:00
2018-06-13 21:08:02 +09:00
}
2018-01-05 09:13:50 +00:00
func (e *Editor) workspaceNew() {
2018-12-28 13:53:55 +09:00
editor.isSetGuiColor = false
2018-01-11 06:11:34 +00:00
ws, err := newWorkspace("")
2018-01-05 09:13:50 +00:00
if err != nil {
return
}
2018-05-20 12:06:29 +09:00
2018-05-01 19:50:47 +09:00
//e.active++
//e.workspaces = append(e.workspaces, nil)
//copy(e.workspaces[e.active+1:], e.workspaces[e.active:])
2018-01-05 09:13:50 +00:00
e.workspaces = append(e.workspaces, nil)
2018-05-01 19:50:47 +09:00
e.active = len(e.workspaces) - 1
2018-01-05 09:13:50 +00:00
e.workspaces[e.active] = ws
2018-01-08 10:23:16 +00:00
e.workspaceUpdate()
}
func (e *Editor) workspaceSwitch(index int) {
index--
if index < 0 || index >= len(e.workspaces) {
return
}
e.active = index
2018-01-05 09:13:50 +00:00
e.workspaceUpdate()
}
func (e *Editor) workspaceNext() {
e.active++
if e.active >= len(e.workspaces) {
e.active = 0
}
e.workspaceUpdate()
}
2018-01-11 06:11:34 +00:00
func (e *Editor) workspacePrevious() {
e.active--
if e.active < 0 {
e.active = len(e.workspaces) - 1
}
e.workspaceUpdate()
}
2018-01-05 09:13:50 +00:00
func (e *Editor) workspaceUpdate() {
if e.wsSide == nil {
return
}
2018-01-05 09:13:50 +00:00
for i, ws := range e.workspaces {
if i == e.active {
ws.hide()
ws.show()
} else {
ws.hide()
}
}
2018-09-22 21:56:33 +09:00
for i := 0; i < len(e.wsSide.items) && i < len(e.workspaces); i++ {
2018-08-28 02:04:53 +09:00
e.wsSide.items[i].setSideItemLabel(i)
2018-04-30 16:39:39 +09:00
e.wsSide.items[i].setText(e.workspaces[i].cwdlabel)
2018-01-08 10:23:16 +00:00
e.wsSide.items[i].show()
}
for i := len(e.workspaces); i < len(e.wsSide.items); i++ {
e.wsSide.items[i].hide()
}
2018-01-05 09:13:50 +00:00
}
2018-01-05 08:07:29 +00:00
func (e *Editor) keyPress(event *gui.QKeyEvent) {
input := e.convertKey(event.Text(), event.Key(), event.Modifiers())
2018-11-29 00:27:52 +09:00
if input == "<C-¥>" {
input = `<C-\>`
}
2018-01-05 08:07:29 +00:00
if input != "" {
2018-11-17 15:22:33 +09:00
if input == "<Esc>" {
e.unfocusGonvimUI()
}
2018-01-05 09:13:50 +00:00
e.workspaces[e.active].nvim.Input(input)
2018-10-08 18:38:48 +09:00
e.workspaces[e.active].detectTerminalMode()
2017-06-06 02:42:11 +01:00
}
2018-01-05 08:07:29 +00:00
}
2017-06-06 02:42:11 +01:00
2018-11-17 15:22:33 +09:00
func (e *Editor) unfocusGonvimUI() {
if e.activity == nil || e.wsSide == nil {
return
}
2018-11-17 15:22:33 +09:00
if e.activity.deinItem.active {
e.deinSide.searchbox.editBox.ClearFocus()
e.deinSide.widget.ClearFocus()
e.deinSide.scrollarea.ClearFocus()
}
if e.activity.editItem.active {
e.wsSide.widget.ClearFocus()
e.wsSide.widget.ClearFocus()
e.wsSide.scrollarea.ClearFocus()
}
}
2018-01-05 08:07:29 +00:00
func (e *Editor) convertKey(text string, key int, mod core.Qt__KeyboardModifier) string {
if mod&core.Qt__KeypadModifier > 0 {
switch core.Qt__Key(key) {
case core.Qt__Key_Home:
return fmt.Sprintf("<%sHome>", e.modPrefix(mod))
case core.Qt__Key_End:
return fmt.Sprintf("<%sEnd>", e.modPrefix(mod))
case core.Qt__Key_PageUp:
return fmt.Sprintf("<%sPageUp>", e.modPrefix(mod))
case core.Qt__Key_PageDown:
return fmt.Sprintf("<%sPageDown>", e.modPrefix(mod))
case core.Qt__Key_Plus:
return fmt.Sprintf("<%sPlus>", e.modPrefix(mod))
case core.Qt__Key_Minus:
return fmt.Sprintf("<%sMinus>", e.modPrefix(mod))
case core.Qt__Key_multiply:
return fmt.Sprintf("<%sMultiply>", e.modPrefix(mod))
case core.Qt__Key_division:
return fmt.Sprintf("<%sDivide>", e.modPrefix(mod))
case core.Qt__Key_Enter:
return fmt.Sprintf("<%sEnter>", e.modPrefix(mod))
case core.Qt__Key_Period:
return fmt.Sprintf("<%sPoint>", e.modPrefix(mod))
case core.Qt__Key_0:
return fmt.Sprintf("<%s0>", e.modPrefix(mod))
case core.Qt__Key_1:
return fmt.Sprintf("<%s1>", e.modPrefix(mod))
case core.Qt__Key_2:
return fmt.Sprintf("<%s2>", e.modPrefix(mod))
case core.Qt__Key_3:
return fmt.Sprintf("<%s3>", e.modPrefix(mod))
case core.Qt__Key_4:
return fmt.Sprintf("<%s4>", e.modPrefix(mod))
case core.Qt__Key_5:
return fmt.Sprintf("<%s5>", e.modPrefix(mod))
case core.Qt__Key_6:
return fmt.Sprintf("<%s6>", e.modPrefix(mod))
case core.Qt__Key_7:
return fmt.Sprintf("<%s7>", e.modPrefix(mod))
case core.Qt__Key_8:
return fmt.Sprintf("<%s8>", e.modPrefix(mod))
case core.Qt__Key_9:
return fmt.Sprintf("<%s9>", e.modPrefix(mod))
}
}
2017-06-16 08:43:05 +01:00
2018-01-05 08:07:29 +00:00
if text == "<" {
return "<lt>"
2017-06-06 02:42:11 +01:00
}
2018-01-05 08:07:29 +00:00
specialKey, ok := e.specialKeys[core.Qt__Key(key)]
if ok {
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), specialKey)
}
2017-06-16 08:43:05 +01:00
2018-10-23 21:14:18 +09:00
if text == "\\" || text == "¥" {
2018-01-05 08:07:29 +00:00
return fmt.Sprintf("<%s%s>", e.modPrefix(mod), "Bslash")
}
2017-06-16 08:43:05 +01:00
2018-01-05 08:07:29 +00:00
c := ""
if mod&e.controlModifier > 0 || mod&e.cmdModifier > 0 {
if int(e.keyControl) == key || int(e.keyCmd) == key || int(e.keyAlt) == key || int(e.keyShift) == key {
return ""
2017-06-06 02:42:11 +01:00
}
2018-01-05 08:07:29 +00:00
c = string(key)
if !(mod&e.shiftModifier > 0) {
c = strings.ToLower(c)
}
} else {
c = text
}
2017-06-06 02:42:11 +01:00
2018-01-05 08:07:29 +00:00
if c == "" {
return ""
}
2017-06-13 16:15:05 +01:00
2018-04-23 00:48:43 +09:00
char := core.NewQChar11(c)
2018-01-05 08:07:29 +00:00
if char.Unicode() < 0x100 && !char.IsNumber() && char.IsPrint() {
mod &= ^e.shiftModifier
2017-07-03 07:14:29 +01:00
}
2018-01-05 08:07:29 +00:00
prefix := e.modPrefix(mod)
if prefix != "" {
return fmt.Sprintf("<%s%s>", prefix, c)
}
return c
}
func (e *Editor) modPrefix(mod core.Qt__KeyboardModifier) string {
prefix := ""
if runtime.GOOS == "linux" || runtime.GOOS == "darwin" {
if mod&e.cmdModifier > 0 {
prefix += "D-"
2017-07-03 07:14:29 +01:00
}
}
2018-01-05 08:07:29 +00:00
if mod&e.controlModifier > 0 {
prefix += "C-"
2017-06-06 02:42:11 +01:00
}
2018-01-05 08:07:29 +00:00
if mod&e.shiftModifier > 0 {
prefix += "S-"
}
2017-06-06 02:42:11 +01:00
2018-01-05 08:07:29 +00:00
if mod&e.altModifier > 0 {
prefix += "A-"
}
return prefix
}
func (e *Editor) initSpecialKeys() {
e.specialKeys = map[core.Qt__Key]string{}
e.specialKeys[core.Qt__Key_Up] = "Up"
e.specialKeys[core.Qt__Key_Down] = "Down"
e.specialKeys[core.Qt__Key_Left] = "Left"
e.specialKeys[core.Qt__Key_Right] = "Right"
e.specialKeys[core.Qt__Key_F1] = "F1"
e.specialKeys[core.Qt__Key_F2] = "F2"
e.specialKeys[core.Qt__Key_F3] = "F3"
e.specialKeys[core.Qt__Key_F4] = "F4"
e.specialKeys[core.Qt__Key_F5] = "F5"
e.specialKeys[core.Qt__Key_F6] = "F6"
e.specialKeys[core.Qt__Key_F7] = "F7"
e.specialKeys[core.Qt__Key_F8] = "F8"
e.specialKeys[core.Qt__Key_F9] = "F9"
e.specialKeys[core.Qt__Key_F10] = "F10"
e.specialKeys[core.Qt__Key_F11] = "F11"
e.specialKeys[core.Qt__Key_F12] = "F12"
e.specialKeys[core.Qt__Key_F13] = "F13"
e.specialKeys[core.Qt__Key_F14] = "F14"
e.specialKeys[core.Qt__Key_F15] = "F15"
e.specialKeys[core.Qt__Key_F16] = "F16"
e.specialKeys[core.Qt__Key_F17] = "F17"
e.specialKeys[core.Qt__Key_F18] = "F18"
e.specialKeys[core.Qt__Key_F19] = "F19"
e.specialKeys[core.Qt__Key_F20] = "F20"
e.specialKeys[core.Qt__Key_F21] = "F21"
e.specialKeys[core.Qt__Key_F22] = "F22"
e.specialKeys[core.Qt__Key_F23] = "F23"
e.specialKeys[core.Qt__Key_F24] = "F24"
e.specialKeys[core.Qt__Key_Backspace] = "BS"
e.specialKeys[core.Qt__Key_Delete] = "Del"
e.specialKeys[core.Qt__Key_Insert] = "Insert"
e.specialKeys[core.Qt__Key_Home] = "Home"
e.specialKeys[core.Qt__Key_End] = "End"
e.specialKeys[core.Qt__Key_PageUp] = "PageUp"
e.specialKeys[core.Qt__Key_PageDown] = "PageDown"
e.specialKeys[core.Qt__Key_Return] = "Enter"
e.specialKeys[core.Qt__Key_Enter] = "Enter"
e.specialKeys[core.Qt__Key_Tab] = "Tab"
e.specialKeys[core.Qt__Key_Backtab] = "Tab"
e.specialKeys[core.Qt__Key_Escape] = "Esc"
e.specialKeys[core.Qt__Key_Backslash] = "Bslash"
e.specialKeys[core.Qt__Key_Space] = "Space"
goos := runtime.GOOS
e.shiftModifier = core.Qt__ShiftModifier
e.altModifier = core.Qt__AltModifier
e.keyAlt = core.Qt__Key_Alt
e.keyShift = core.Qt__Key_Shift
if goos == "darwin" {
e.controlModifier = core.Qt__MetaModifier
e.cmdModifier = core.Qt__ControlModifier
e.metaModifier = core.Qt__AltModifier
e.keyControl = core.Qt__Key_Meta
e.keyCmd = core.Qt__Key_Control
} else {
e.controlModifier = core.Qt__ControlModifier
e.metaModifier = core.Qt__MetaModifier
e.keyControl = core.Qt__Key_Control
if goos == "linux" {
e.cmdModifier = core.Qt__MetaModifier
e.keyCmd = core.Qt__Key_Meta
}
}
2017-06-06 02:42:11 +01:00
}
2018-01-08 10:23:16 +00:00
func (e *Editor) close() {
e.stopOnce.Do(func() {
close(e.stop)
})
}
func (e *Editor) cleanup() {
home, err := homedir.Dir()
if err != nil {
return
}
sessions := filepath.Join(home, ".gonvim", "sessions")
os.RemoveAll(sessions)
os.MkdirAll(sessions, 0755)
2018-01-11 06:11:34 +00:00
select {
case <-e.stop:
return
default:
}
2018-01-08 10:23:16 +00:00
for i, ws := range e.workspaces {
sessionPath := filepath.Join(sessions, strconv.Itoa(i)+".vim")
fmt.Println(sessionPath)
fmt.Println(ws.nvim.Command("mksession " + sessionPath))
fmt.Println("mksession finished")
}
}