Skip to content

Commit

Permalink
Merge pull request #21 from mathaou/release/0.7-alpha
Browse files Browse the repository at this point in the history
Release/0.7 alpha
  • Loading branch information
Matt Farstad authored Sep 23, 2021
2 parents f9d1ccf + e3648ce commit 539aad1
Show file tree
Hide file tree
Showing 14 changed files with 405 additions and 164 deletions.
34 changes: 25 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,26 @@

![Serialization](https://i.imgur.com/GhMcnid.gif)

#### Query your database!

![querying](https://i.imgur.com/9FB3ETs.gif)

#### Other Features

- Run SQL queries and display the results!
- Update, delete, or insert with SQL, with undo/redo supported
- Automatic JSON formatting in selection/format mode
- Edit multi-line text with vim-like controls
- Undo/Redo of changes (SQLite only)
- Themes (press T in table mode)
- Output query results as a csv

#### Roadmap

- Run SQL queries and display results
- Add/remove rows/columns/cells
- Filter tables by fuzzy search
- MySQL/ PostgreSQL support
- Line wrapping / horizontal scroll for format/SQL mode

####
<details>
Expand Down Expand Up @@ -63,17 +70,18 @@
Whatever terminal emulator used should support ANSI escape sequences. If there is an option for 256 color mode, enable it. If not available, try running program in ascii mode (-a).

#### Known Issues
- Using termdbms over a serial connection works very poorly. This is due to ANSI sequences not being supported natively. Maybe putty/mobaxterm have settings to allow this?
- The headers wig out sometimes in selection mode
- Mouse down does not work in Windows Terminal, but it does work in Command Prompt.
- Tab in format mode does not work at the end of lines or empty lines.
- Line wrapping is not yet implemented, so text in format mode should be less than the maximum number of columns available per line for best use. It's in the works!

##### Help:
-p / database path (absolute)
-d / specifies which database driver to use (sqlite/mysql)
-a / enable ascii mode
-h / prints this message
-t / starts app with specific theme (default, nord, solarized)
-p / database path (absolute)
-d / specifies which database driver to use (sqlite/mysql)
-a / enable ascii mode
-h / prints this message
-t / starts app with specific theme (default, nord, solarized)
##### Controls:
###### MOUSE
Scroll up + down to navigate table/text
Expand All @@ -90,24 +98,25 @@ Whatever terminal emulator used should support ANSI escape sequences. If there i
[B] to toggle borders!
[C] to expand column
[T] to cycle through themes!
[P] in selection mode to write cell to file
[P] in selection mode to write cell to file, or to print query results as CSV.
[R] to redo actions, if applicable
[U] to undo actions, if applicable
[ESC] to exit full screen view, or to enter edit mode
[PGDOWN] to scroll down one views worth of rows
[PGUP] to scroll up one views worth of rows
###### EDIT MODE (for quick, single line changes)
###### EDIT MODE (for quick, single line changes and commands)
[ESC] to enter edit mode with no pre-loaded text input from selection
When a cell is selected, press [:] to enter edit mode with selection pre-loaded
The text field in the header will be populated with the selected cells text. Modifications can be made freely
[ESC] to clear text field in edit mode
[ENTER] to save text. Anything besides one of the reserved strings below will overwrite the current cell
[:q] to exit edit mode
[:q] to exit edit mode/ format mode/ SQL mode
[:s] to save database to a new file (SQLite only)
[:s!] to overwrite original database file (SQLite only). A confirmation dialog will be added soon
[:h] to display help text
[:new] opens current cell with a blank buffer
[:edit] opens current cell in format mode
[:sql] opens blank buffer for creating an SQL statement
[HOME] to set cursor to end of the text
[END] to set cursor to the end of the text
###### FORMAT MODE (for editing lines of text)
Expand All @@ -118,3 +127,10 @@ Whatever terminal emulator used should support ANSI escape sequences. If there i
[:w] to save changes and remain in format view
[:s] to serialize changes, non-destructive (SQLite only)
[:s!] to serialize changes, overwriting original file (SQLite only)
###### SQL MODE (for querying database)
[ESC] to move between top control bar and text buffer
[:q] to quit out of statement
[:exec] to execute statement. Errors will be displayed in full screen view.
###### QUERY MODE (specifically when viewing query results)
[:d] to reset table data back to original view
[:sql] to query original database again
3 changes: 2 additions & 1 deletion database/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ type SQLite struct {
func (db *SQLite) Update(q *Update) {
protoQuery, columnOrder := db.GenerateQuery(q)
values := make([]interface{}, len(columnOrder))
updateValues := q.GetValues()
for i, v := range columnOrder {
if i == 0 {
values[i] = q.Update
} else {
values[i] = q.GetValues()[v]
values[i] = updateValues[v]
}
}
tx, err := db.GetDatabaseReference().Begin()
Expand Down
8 changes: 6 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ func main() {
m := GetNewModel(dst, db)
InitialModel = &m
InitialModel.InitialFileName = path
SetModel(InitialModel, c, db, m.Table.Database.GetTableNamesQuery())
err := SetModel(InitialModel, c, db)
if err != nil {
fmt.Printf("%v", err)
os.Exit(1)
}

// creates the program
Program = tea.NewProgram(InitialModel,
Expand Down Expand Up @@ -157,4 +161,4 @@ func handleFlags() {
}

database.DriverString = databaseType
}
}
1 change: 0 additions & 1 deletion tuiutil/textinput.go
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,6 @@ func (m TextInputModel) View() string {
pos := max(0, m.pos-m.Offset)
v := styleText(m.echoTransform(string(value[:pos])))

// TODO ascii terminal styling
if pos < len(value) {
if Ascii {
v += "¦"
Expand Down
57 changes: 34 additions & 23 deletions viewer/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,50 +119,56 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {
}
break
case "r": // redo
if len(m.RedoStack) > 0 { // do this after you get undo working, basically just the same thing reversed
if len(m.RedoStack) > 0 && m.QueryResult == nil && m.QueryData == nil { // do this after you get undo working, basically just the same thing reversed
// handle undo
deepCopy := m.CopyMap()
// THE GLOBALIST TAKEOVER
deepState := TableState{
Database: &database.SQLite{
FileName: m.Table.Database.GetFileName(),
Database: nil,
FileName: m.Table().Database.GetFileName(),
Database: nil,
}, // placeholder for now while testing database copy
Data: deepCopy,
}
m.UndoStack = append(m.UndoStack, deepState)
// handle redo
from := m.RedoStack[len(m.RedoStack)-1]
to := m.Table
SwapTableValues(m, &from, &to)
m.Table.Database.SetDatabaseReference(from.Database.GetFileName())
to := m.Table()
SwapTableValues(m, &from, to)
m.Table().Database.CloseDatabaseReference()
m.Table().Database.SetDatabaseReference(from.Database.GetFileName())

m.RedoStack = m.RedoStack[0 : len(m.RedoStack)-1] // pop
}
break
case "u": // undo
if len(m.UndoStack) > 0 {
if len(m.UndoStack) > 0 && m.QueryResult == nil && m.QueryData == nil {
// handle redo
deepCopy := m.CopyMap()
t := m.Table()
// THE GLOBALIST TAKEOVER
deepState := TableState{
Database: &database.SQLite{
FileName: m.Table.Database.GetFileName(),
Database: nil,
FileName: t.Database.GetFileName(),
Database: nil,
}, // placeholder for now while testing database copy
Data: deepCopy,
}
m.RedoStack = append(m.RedoStack, deepState)
// handle undo
from := m.UndoStack[len(m.UndoStack)-1]
to := m.Table
SwapTableValues(m, &from, &to)
m.Table.Database.SetDatabaseReference(from.Database.GetFileName())
to := t
SwapTableValues(m, &from, to)
t.Database.CloseDatabaseReference()
t.Database.SetDatabaseReference(from.Database.GetFileName())

m.UndoStack = m.UndoStack[0 : len(m.UndoStack)-1] // pop
}
break
case ":": // edit mode or format mode depending on string length
if m.QueryData != nil || m.QueryResult != nil { // editing not allowed in query view mode
break
}
m.UI.EditModeEnabled = true
raw, _, _ := m.GetSelectedOption()
if raw == nil {
Expand All @@ -178,10 +184,11 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {
cmd = m.FormatInput.Model.FocusCommand() // get focus
m.Scroll.PreScrollYOffset = m.Viewport.YOffset // store scrolling so state can be restored on exit
m.Scroll.PreScrollYPosition = m.MouseData.Y
d := m.Data()
if conv, err := FormatJson(str); err == nil { // if json prettify
m.Data.EditTextBuffer = conv
d.EditTextBuffer = conv
} else {
m.Data.EditTextBuffer = str
d.EditTextBuffer = str
}
m.FormatInput.Original = raw // pointer to original data
m.Format.Text = GetFormattedTextBuffer(m)
Expand All @@ -195,7 +202,9 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {
break
case "p":
if m.UI.RenderSelection {
WriteTextFile(m, m.Data.EditTextBuffer)
WriteTextFile(m, m.Data().EditTextBuffer)
} else if m.QueryData != nil || m.QueryResult != nil {
WriteCSV(m)
}
break
case "c":
Expand All @@ -205,7 +214,7 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {
m.UI.BorderToggle = !m.UI.BorderToggle
break
case "up", "k": // toggle next schema + 1
if m.UI.CurrentTable == len(m.Data.TableIndexMap) {
if m.UI.CurrentTable == len(m.Data().TableIndexMap) {
m.UI.CurrentTable = 1
} else {
m.UI.CurrentTable++
Expand All @@ -220,7 +229,7 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {
break
case "down", "j": // toggle previous schema - 1
if m.UI.CurrentTable == 1 {
m.UI.CurrentTable = len(m.Data.TableIndexMap)
m.UI.CurrentTable = len(m.Data().TableIndexMap)
} else {
m.UI.CurrentTable--
}
Expand Down Expand Up @@ -249,10 +258,11 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {

if m.MouseData.Y-HeaderHeight+m.Viewport.YOffset < max-1 {
m.MouseData.Y++
ceiling := m.Viewport.Height+HeaderHeight-1
tuiutil.Clamp(m.MouseData.Y, m.MouseData.Y + 1, ceiling)
ceiling := m.Viewport.Height + HeaderHeight - 1
tuiutil.Clamp(m.MouseData.Y, m.MouseData.Y+1, ceiling)
if m.MouseData.Y > ceiling {
ScrollDown(m)
m.MouseData.Y = ceiling
}
}

Expand All @@ -268,7 +278,7 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {
break
case "d": // manual keyboard control for column ++
col := m.GetColumn()
cols := len(m.Data.TableHeadersSlice) - 1
cols := len(m.Data().TableHeadersSlice) - 1
if (m.MouseData.X-m.Viewport.Width) <= cw && m.GetColumn() < cols { // within tolerances
m.MouseData.X += cw
} else if col == cols {
Expand Down Expand Up @@ -300,15 +310,16 @@ func HandleKeyboardEvents(m *TuiModel, msg *tea.KeyMsg) tea.Cmd {
ScrollDown(m)
break
case "esc": // exit full screen cell value view, also enabled edit mode
if !m.UI.RenderSelection && !m.UI.HelpDisplay {
m.TextInput.Model.SetValue("")
if !m.UI.RenderSelection &&
!m.UI.HelpDisplay {
m.UI.EditModeEnabled = true
break
}
m.UI.RenderSelection = false
m.UI.HelpDisplay = false
m.Data.EditTextBuffer = ""
m.Data().EditTextBuffer = ""
cmd = m.TextInput.Model.FocusCommand()
m.TextInput.Model.SetValue("")
m.UI.ExpandColumn = -1
m.MouseData.Y = m.Scroll.PreScrollYPosition
m.Viewport.YOffset = m.Scroll.PreScrollYOffset
Expand Down
16 changes: 12 additions & 4 deletions viewer/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,25 @@ func GetHelpText() (help string) {
[B] to toggle borders!
[C] to expand column
[T] to cycle through themes!
[P] in selection mode to write cell to file
[P] in selection mode to write cell to file, or to print query results as CSV.
[R] to redo actions, if applicable
[U] to undo actions, if applicable
[ESC] to exit full screen view, or to enter edit mode
[PGDOWN] to scroll down one views worth of rows
[PGUP] to scroll up one views worth of rows
###### EDIT MODE (for quick, single line changes)
###### EDIT MODE (for quick, single line changes and commands)
[ESC] to enter edit mode with no pre-loaded text input from selection
When a cell is selected, press [:] to enter edit mode with selection pre-loaded
The text field in the header will be populated with the selected cells text. Modifications can be made freely
[ESC] to clear text field in edit mode
[ENTER] to save text. Anything besides one of the reserved strings below will overwrite the current cell
[:q] to exit edit mode
[:q] to exit edit mode/ format mode/ SQL mode
[:s] to save database to a new file (SQLite only)
[:s!] to overwrite original database file (SQLite only). A confirmation dialog will be added soon
[:h] to display help text
[:new] opens current cell with a blank buffer
[:edit] opens current cell in format mode
[:sql] opens blank buffer for creating an SQL statement
[HOME] to set cursor to end of the text
[END] to set cursor to the end of the text
###### FORMAT MODE (for editing lines of text)
Expand All @@ -51,7 +52,14 @@ func GetHelpText() (help string) {
[:wq] to save changes and quit to main table view
[:w] to save changes and remain in format view
[:s] to serialize changes, non-destructive (SQLite only)
[:s!] to serialize changes, overwriting original file (SQLite only)`
[:s!] to serialize changes, overwriting original file (SQLite only)
###### SQL MODE (for querying database)
[ESC] to move between top control bar and text buffer
[:q] to quit out of statement
[:exec] to execute statement. Errors will be displayed in full screen view.
###### QUERY MODE (specifically when viewing query results)
[:d] to reset table data back to original view
[:sql] to query original database again`

return help
}
Loading

0 comments on commit 539aad1

Please sign in to comment.