7 Commits
9 changed files with 104 additions and 48 deletions
+1
View File
@@ -6,5 +6,6 @@ selected_style_fallback: "default-fallback" # Style for 8-color capable terminal
show_top_menu: true
show_line_index: true
extend_line_index: false # Extend line index to the bottom of the screen
color_message_bar: true # Add color to message bar messages
buffer_info_message: "File: %f, Filetype: %t, Cursor: (%x, %y, %p), Chars: %c"
tab_indentation: 4 # Length of tab characters
+8 -10
View File
@@ -604,7 +604,7 @@ func GetOpenFileBuffer(filename string) *Buffer {
return nil
}
func CreateFileBuffer(filename string, openNonExistentFile bool) (*Buffer, error) {
func CreateFileBuffer(filename string) (*Buffer, error) {
// Replace tilde with home directory
if filename != "~" && strings.HasPrefix(filename, "~/") {
homedir, err := os.UserHomeDir()
@@ -623,22 +623,20 @@ func CreateFileBuffer(filename string, openNonExistentFile bool) (*Buffer, error
}
stat, err := os.Stat(abs)
if !openNonExistentFile {
if err != nil {
if err != nil {
if !os.IsNotExist(err) {
return nil, err
}
if !stat.Mode().IsRegular() {
return nil, fmt.Errorf("%s is not a regular file", filename)
}
} else if !stat.Mode().IsRegular() {
return nil, fmt.Errorf("not a regular file")
}
if GetBufferByName(filename) != nil {
return nil, fmt.Errorf("a buffer with the name (%s) is already open", filename)
return nil, fmt.Errorf("a buffer with the same name is already open")
}
if GetBufferByFilename(abs) != nil {
return nil, fmt.Errorf("%s is already open in another buffer", filename)
return nil, fmt.Errorf("file is already open in another buffer")
}
buffer := Buffer{
@@ -675,7 +673,7 @@ func CreateBuffer(bufferName string) (*Buffer, error) {
}
if GetBufferByName(bufferName) != nil {
return nil, fmt.Errorf("a buffer with the name (%s) is already open", bufferName)
return nil, fmt.Errorf("a buffer with the same name is already open")
}
Buffers = append(Buffers, &buffer)
+2 -2
View File
@@ -141,9 +141,9 @@ func initCommands() {
window.PrintMessage(fmt.Sprintf("File already open! Switching to buffer: %s", openBuffer.Name), TYPER_MESSAGE_INFO)
window.CurrentBuffer = openBuffer
} else {
newBuffer, err := CreateFileBuffer(input, false)
newBuffer, err := CreateFileBuffer(input)
if err != nil {
window.PrintMessage(fmt.Sprintf("Could not open file: %s", err.Error()), TYPER_MESSAGE_WARNING)
window.PrintMessage(fmt.Sprintf("Could not open file %s: %s", input, err), TYPER_MESSAGE_ERROR)
return
}
+1
View File
@@ -12,6 +12,7 @@ type TyperConfig struct {
FallbackStyle string `yaml:"fallback_style,omitempty"`
ShowTopMenu bool `yaml:"show_top_menu,omitempty"`
ShowLineIndex bool `yaml:"show_line_index,omitempty"`
ColorMessageBar bool `yaml:"color_message_bar"`
ExtendLineIndex bool `yaml:"extend_line_index,omitempty"`
BufferInfoMessage string `yaml:"buffer_info_message,omitempty"`
TabIndentation int `yaml:"tab_indentation,omitempty"`
+24 -16
View File
@@ -1,6 +1,7 @@
package main
import (
"fmt"
"log"
flag "github.com/spf13/pflag"
@@ -34,29 +35,36 @@ func main() {
log.Fatalf("Failed to create window: %v", err)
}
if flag.NArg() > 0 {
for i, file := range flag.Args() {
b, err := CreateFileBuffer(file, true)
if err != nil {
window.PrintMessage("Could not open file: "+file, TYPER_MESSAGE_ERROR)
continue
}
if i == 0 {
window.CurrentBuffer = b
Buffers = Buffers[1:]
}
}
}
// Create logs buffer
logsBuffer, err := CreateBuffer("Logs")
logsBuffer, err := CreateBuffer("Typer Logs")
if err != nil {
log.Fatalf("Could not create logs buffer")
}
logsBuffer.filetype = "typer_logs"
logsBuffer.canEdit = false
// Open paths passed as arguments
if flag.NArg() > 0 {
for _, file := range flag.Args() {
buffer, err := CreateFileBuffer(file)
if err != nil {
window.PrintMessage(fmt.Sprintf("Could not open file %s: %s", file, err), TYPER_MESSAGE_ERROR)
continue
}
if window.CurrentBuffer == nil {
window.CurrentBuffer = buffer
}
}
}
if window.CurrentBuffer == nil {
buffer, err := CreateBuffer("New Buffer 1")
if err == nil {
window.CurrentBuffer = buffer
}
}
for !window.closed {
window.Draw()
window.ProcessEvents()
+10 -1
View File
@@ -27,7 +27,7 @@ var lastMessage *TyperMessage
func (window *Window) PrintMessage(message string, urgency TyperMessageUrgency) {
lastMessage = &TyperMessage{Timestamp: time.Now().UnixMilli(), Message: message, Urgency: urgency}
logsBuffer := GetBufferByName("Logs")
logsBuffer := GetBufferByName("Typer Logs")
if logsBuffer != nil {
messageToPrint := ""
switch lastMessage.Urgency {
@@ -82,10 +82,19 @@ func drawMessageBar(window *Window) {
if lastMessage != nil && time.Since(time.UnixMilli(lastMessage.Timestamp)).Seconds() < 5 {
switch lastMessage.Urgency {
case TYPER_MESSAGE_INFO:
if Config.ColorMessageBar {
messageBarStyle = messageBarStyle.Foreground(CurrentStyle.SyntaxInfo)
}
messageToPrint = "[INFO] "
case TYPER_MESSAGE_WARNING:
if Config.ColorMessageBar {
messageBarStyle = messageBarStyle.Foreground(CurrentStyle.SyntaxWarning)
}
messageToPrint = "[WARNING] "
case TYPER_MESSAGE_ERROR:
if Config.ColorMessageBar {
messageBarStyle = messageBarStyle.Foreground(CurrentStyle.SyntaxError)
}
messageToPrint = "[ERROR] "
default:
messageToPrint = "[???] "
+24 -6
View File
@@ -5,6 +5,7 @@ import (
"path/filepath"
"strconv"
"strings"
"typer/runestring"
"github.com/gdamore/tcell/v2"
)
@@ -85,9 +86,11 @@ func initTopMenu() {
}
buffersSlice := make([]string, 0)
selected := 0
for i, buffer := range Buffers {
if window.CurrentBuffer == buffer {
buffersSlice = append(buffersSlice, fmt.Sprintf("[%d] * %s", i+1, buffer.Name))
selected = i
} else {
buffersSlice = append(buffersSlice, fmt.Sprintf("[%d] %s", i+1, buffer.Name))
}
@@ -99,6 +102,7 @@ func initTopMenu() {
ClearDropdowns()
window.CursorMode = CursorModeBuffer
})
d.Selected = selected
ActiveDropdown = d
window.CursorMode = CursorModeDropdown
},
@@ -148,9 +152,7 @@ func getBufferInfoMsg(window *Window) string {
filetype = window.CurrentBuffer.filetype
}
contents := window.CurrentBuffer.GetContentsAsString()
chars := len(contents)
words := len(strings.Fields(string(contents)))
var contents runestring.RuneString = nil
ret := Config.BufferInfoMessage
@@ -160,9 +162,25 @@ func getBufferInfoMsg(window *Window) string {
ret = strings.ReplaceAll(ret, "%t", filetype)
ret = strings.ReplaceAll(ret, "%x", strconv.Itoa(window.CurrentBuffer.CursorPos.X+1))
ret = strings.ReplaceAll(ret, "%y", strconv.Itoa(window.CurrentBuffer.CursorPos.Y+1))
ret = strings.ReplaceAll(ret, "%p", strconv.Itoa(window.CurrentBuffer.PositionToAbsolutePosition(window.CurrentBuffer.CursorPos)+1))
ret = strings.ReplaceAll(ret, "%c", strconv.Itoa(chars))
ret = strings.ReplaceAll(ret, "%w", strconv.Itoa(words))
// Only replace if found for expensive calls
if strings.Contains(ret, "%p") {
ret = strings.ReplaceAll(ret, "%p", strconv.Itoa(window.CurrentBuffer.PositionToAbsolutePosition(window.CurrentBuffer.CursorPos)+1))
}
if strings.Contains(ret, "%c") {
contents = window.CurrentBuffer.GetContentsAsString()
chars := len(contents)
ret = strings.ReplaceAll(ret, "%c", strconv.Itoa(chars))
}
if strings.Contains(ret, "%w") {
if contents == nil {
contents = window.CurrentBuffer.GetContentsAsString()
}
words := len(strings.Fields(string(contents)))
ret = strings.ReplaceAll(ret, "%w", strconv.Itoa(words))
}
return ret
}
+1 -2
View File
@@ -3,7 +3,6 @@ package main
import (
"log"
"os"
"path"
"path/filepath"
"runtime"
@@ -23,7 +22,7 @@ func GetConfigPath(relativeConfigPath string) string {
paths := make([]string, 0)
if *configDirFlag != "" {
paths = append(paths, path.Join(*configDirFlag, relativeConfigPath))
paths = append(paths, filepath.Join(*configDirFlag, relativeConfigPath))
}
switch runtime.GOOS {
case "windows":
+33 -11
View File
@@ -4,7 +4,6 @@ import (
"fmt"
"log"
"slices"
"strconv"
"strings"
"time"
"typer/runestring"
@@ -57,14 +56,6 @@ func CreateWindow() (*Window, error) {
screen: nil,
}
// Create empty buffer if nil
for i := 1; window.CurrentBuffer == nil; i++ {
buffer, err := CreateBuffer("New Buffer " + strconv.Itoa(i))
if err == nil {
window.CurrentBuffer = buffer
}
}
// Create tcell screen
screen, err := tcell.NewScreen()
if err != nil {
@@ -491,9 +482,40 @@ func (window *Window) handleMouseInput(ev *tcell.EventMouse) {
if ev.Buttons() == tcell.Button1 {
// Get last click time
lastClickTime := time.UnixMilli(lastClick)
// Ensure click was in buffer area
x1, y1, x2, y2 := window.GetTextAreaDimensions()
if mouseX >= x1 && mouseY >= y1 && mouseX <= x2 && mouseY <= y2 {
if mouseY == 0 && Config.ShowTopMenu && !mouseHeld {
// Mouse is in top menu
// Find clicked button
buttonFound := false
for _, button := range TopMenuButtons {
if mouseX >= button.PosX && mouseX <= button.PosX+len(button.Name) {
buttonFound = true
button.Action(window, &button)
}
}
if !buttonFound {
// Exit top menu
ClearDropdowns()
window.CursorMode = CursorModeBuffer
}
} else if window.CursorMode == CursorModeDropdown && !mouseHeld {
// Mouse is in top menu
if mouseX >= ActiveDropdown.PosX && mouseX <= ActiveDropdown.PosX+ActiveDropdown.Width+1 && mouseY > ActiveDropdown.PosY && mouseY <= ActiveDropdown.PosY+len(ActiveDropdown.Options) {
// Dropdown button clicked
ActiveDropdown.Selected = mouseY - ActiveDropdown.PosY - 1
ActiveDropdown.Action(ActiveDropdown.Selected)
} else {
// Exit top menu
ClearDropdowns()
window.CursorMode = CursorModeBuffer
}
} else if mouseX >= x1 && mouseY >= y1 && mouseX <= x2 && mouseY <= y2 && window.CursorMode == CursorModeBuffer {
// Mouse is in buffer area
currentPos := window.CurrentBuffer.CursorPos
mouseBufferPos := Position{mouseX + window.CurrentBuffer.Offset.X - x1, mouseY + window.CurrentBuffer.Offset.Y - y1}