package main import ( "fmt" "os" "path/filepath" "strings" "tildegit.org/sloum/tally/qline" "tildegit.org/sloum/tally/termios" "time" ) const ( Left rune = 'h' Right rune = 'l' Up rune = 'k' Down rune = 'j' Quit rune = 'Q' Edit rune = '\n' EditAlt rune = ' ' EditText rune = '"' Del rune = 'd' Com rune = ':' ZoomIn rune = '+' ZoomOut rune = '-' Yank rune = 'y' Paste rune = 'p' PasteRelative rune = 'P' ToTop rune = 'g' ToBottom rune = 'G' RowStart rune = '^' RowEnd rune = '$' ModBold rune = 'b' ModFaint rune = 'f' ModItalic rune = 'i' ModUnderline rune = 'u' OpenLink rune = 'O' ) type workbook struct { name string path string sheets []sheet sheet int termRows int termCols int } func (w *workbook) PollForTermSize() { for { var cols, rows = termios.GetWindowSize() if rows != w.termRows || cols != w.termCols { w.termRows = rows w.termCols = cols fmt.Print("\033[2J") w.Draw() } time.Sleep(500 * time.Millisecond) } } func (w workbook) Draw() { fmt.Print("\033[0;0H") fmt.Printf("FILE: \033[1m%-*.*s\033[0m\n", w.termCols-6, w.termCols-6, w.path) fmt.Printf("EXPR: %-*.*s\n", w.termCols-6, w.termCols-6, w.sheets[w.sheet].CurrentValue(true)) w.sheets[w.sheet].Draw(w.termCols,w.termRows) } func (w *workbook) Run() { defer termios.Restore() termios.SetCharMode() fmt.Print("\033[?25l\033[2J") go w.PollForTermSize() var input rune var chErr error for { w.Draw() input, chErr = Getch() if chErr != nil { continue } switch input { case Left, Right, Up, Down, ToTop, RowStart, ToBottom, RowEnd, qline.LeftArrow, qline.RightArrow, qline.DownArrow, qline.UpArrow, qline.Home, qline.End, qline.PageUp, qline.PageDown: w.sheets[w.sheet].moveSelection(input, w.termRows) case Quit: if modified { fmt.Print("There are unsaved changes. Quit anyway? [y/n]") answer, err := Getch() if err != nil || answer == 'n' || answer == 'N' { continue } fmt.Print("\n") } termios.Restore() fmt.Print("\033[?25h") os.Exit(0) case Edit, EditAlt, EditText: quote := false if input == EditText { quote = true } w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].Edit(w.sheets[w.sheet].selection.row, w.sheets[w.sheet].selection.col, w.termCols, quote) w.sheets[w.sheet].Recalculate() case Del, qline.Delete, qline.BackSpace: w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1] = cell{} w.sheets[w.sheet].Recalculate() case Com: line := GetEditLine(":", "", w.termCols) runCommand(strings.Fields(line)) case ZoomIn: w.sheets[w.sheet].ZoomIn() fmt.Print("\033[2J") case ZoomOut: w.sheets[w.sheet].ZoomOut() fmt.Print("\033[2J") case Yank: w.sheets[w.sheet].Yank() case Paste: w.sheets[w.sheet].Paste() w.sheets[w.sheet].Recalculate() case PasteRelative: w.sheets[w.sheet].PasteRelative() w.sheets[w.sheet].Recalculate() case ModBold: w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Bold) case ModFaint: w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Faint) case ModItalic: w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Italic) case ModUnderline: w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].ToggleMod(Underline) case OpenLink: url := w.sheets[w.sheet].cells[w.sheets[w.sheet].selection.row-1][w.sheets[w.sheet].selection.col-1].mask if IsURL(url) { OpenInBrowser(url) } } } } func makeWorkbook(path string) workbook { // TODO parse path and get file name // set name of strict to the filename // or untitled.qsh if no filename; set // path to the full path cols, rows := termios.GetWindowSize() sh := makeSheet("Sheet1") wb = workbook{filepath.Base(path), path, make([]sheet,1), 0, rows, cols} wb.sheets[0] = sh return wb } func (w workbook) header() string { return fmt.Sprintf("\033[1;7m %s \033[0m %s\n",w.name, w.sheets[w.sheet].name) }