Have made some large improvements
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build / build (push) Successful in 2m48s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build / build (push) Successful in 2m48s
				
			- Added support for multiple cursors - Enabled wrapping - Added uppercase, lowercase, and lorem ipsum support - Added support for processing only selected ranges
This commit is contained in:
		
							parent
							
								
									a047d89dad
								
							
						
					
					
						commit
						3a23118036
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
build
 | 
					build
 | 
				
			||||||
node_modules
 | 
					node_modules
 | 
				
			||||||
frontend/dist
 | 
					frontend/dist
 | 
				
			||||||
 | 
					.DS_Store
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,8 +15,11 @@
 | 
				
			||||||
            data-action="keyup.enter->commands#runCommand keydown.esc->commands#dismissDialog keyup->commands#handleKeyup">
 | 
					            data-action="keyup.enter->commands#runCommand keydown.esc->commands#dismissDialog keyup->commands#handleKeyup">
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <select multiple class="command-options" data-commands-target="commandSelect">
 | 
					      <select multiple class="command-options" data-commands-target="commandSelect">
 | 
				
			||||||
 | 
					        <option value="format-json"><span class="option-label">JSON: Format</span></option>
 | 
				
			||||||
 | 
					        <option value="lorem-ipsum"><span class="option-label">Lorem Ipsum: Generate</span></option>
 | 
				
			||||||
 | 
					        <option value="lower-case"><span class="option-label">Lower Case</span></option>
 | 
				
			||||||
        <option value="unquote"><span class="option-label">Unquote</span></option>
 | 
					        <option value="unquote"><span class="option-label">Unquote</span></option>
 | 
				
			||||||
        <option value="format-json"><span class="option-label">Format JSON</span></option>
 | 
					        <option value="upper-case"><span class="option-label">Upper Case</span></option>
 | 
				
			||||||
      </select>
 | 
					      </select>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </dialog>
 | 
					  </dialog>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
.cm-editor {
 | 
					.cm-editor {
 | 
				
			||||||
    height: 100%;
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
    font-size: 1.1em;
 | 
					    font-size: 1.1em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								frontend/src/cmplugins.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								frontend/src/cmplugins.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					import {EditorSelection} from "@codemirror/state";
 | 
				
			||||||
 | 
					import {keymap} from "@codemirror/view";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function spawnNewCursor(view, forward) {
 | 
				
			||||||
 | 
					    const { state } = view
 | 
				
			||||||
 | 
					    const selection = state.selection
 | 
				
			||||||
 | 
					    const newRanges = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (let range of selection.ranges) {
 | 
				
			||||||
 | 
					        // Keep existing cursor
 | 
				
			||||||
 | 
					        newRanges.push(range)
 | 
				
			||||||
 | 
					        newRanges.push(view.moveVertically(range, forward, 1));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    view.dispatch({
 | 
				
			||||||
 | 
					        selection: EditorSelection.create(newRanges)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const multiCursorKeymap = keymap.of([
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        key: "Ctrl-Alt-ArrowDown", // Control+Option+Down on Mac
 | 
				
			||||||
 | 
					        run: (view) => spawnNewCursor(view, true),
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        key: "Ctrl-Alt-ArrowUp", // Control+Option+Down on Mac
 | 
				
			||||||
 | 
					        run: (view) => spawnNewCursor(view, false),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const commandPalette = keymap.of([{
 | 
				
			||||||
 | 
					    key: "Cmd-p",
 | 
				
			||||||
 | 
					    run: () => {
 | 
				
			||||||
 | 
					        let event = new CustomEvent('dq-showcommands');
 | 
				
			||||||
 | 
					        window.dispatchEvent(event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}]);
 | 
				
			||||||
| 
						 | 
					@ -2,26 +2,22 @@ import './style.css';
 | 
				
			||||||
import './app.css';
 | 
					import './app.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {EditorView, basicSetup} from "codemirror";
 | 
					import {EditorView, basicSetup} from "codemirror";
 | 
				
			||||||
import {keymap} from "@codemirror/view";
 | 
					import {Application} from "@hotwired/stimulus";
 | 
				
			||||||
import { Application } from "@hotwired/stimulus";
 | 
					
 | 
				
			||||||
 | 
					import {textProcessor} from "./services.js";
 | 
				
			||||||
 | 
					import {multiCursorKeymap, commandPalette} from "./cmplugins.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { textProcessor } from "./services.js";
 | 
					 | 
				
			||||||
import {CommandsController} from "./controllers/commands_controller.js";
 | 
					import {CommandsController} from "./controllers/commands_controller.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const view = new EditorView({
 | 
					const view = new EditorView({
 | 
				
			||||||
    parent: document.querySelector("#app"),
 | 
					    parent: document.querySelector("#app"),
 | 
				
			||||||
    doc: "",
 | 
					    doc: "",
 | 
				
			||||||
    extensions: [
 | 
					    extensions: [
 | 
				
			||||||
        basicSetup,
 | 
					        basicSetup,
 | 
				
			||||||
        keymap.of([{
 | 
					        EditorView.lineWrapping,
 | 
				
			||||||
            key: "Cmd-p",
 | 
					        multiCursorKeymap,
 | 
				
			||||||
            run: () => {
 | 
					        commandPalette,
 | 
				
			||||||
                let event = new CustomEvent('dq-showcommands');
 | 
					 | 
				
			||||||
                window.dispatchEvent(event);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }]),
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,11 +18,27 @@ class TextProcessor {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let ranges = this._editor.state.selection.ranges;
 | 
				
			||||||
 | 
					        let shouldBeAll = ranges.reduce((a, r) => a && r.from === r.to, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let inputs = [];
 | 
				
			||||||
 | 
					        if (shouldBeAll) {
 | 
				
			||||||
 | 
					            inputs.push({
 | 
				
			||||||
 | 
					                text: this._editor.state.doc.toString(),
 | 
				
			||||||
 | 
					                pos: 0,
 | 
				
			||||||
 | 
					                len: this._editor.state.doc.length,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            inputs = ranges.map(r => ({
 | 
				
			||||||
 | 
					                text: this._editor.state.doc.slice(r.from, r.to).toString(),
 | 
				
			||||||
 | 
					                pos: r.from,
 | 
				
			||||||
 | 
					                len: r.to - r.from,
 | 
				
			||||||
 | 
					            }))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ProcessText({
 | 
					        ProcessText({
 | 
				
			||||||
            action: command,
 | 
					            action: command,
 | 
				
			||||||
            input: [
 | 
					            input: inputs,
 | 
				
			||||||
                {text:  this._editor.state.doc.toString(), pos: 0, len: this._editor.state.doc.length}
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,22 +1,46 @@
 | 
				
			||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type TextFilter func(input string) (output string, err error)
 | 
					type TextFilter func(input string) (output string, err error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var TextFilters = map[string]TextFilter{
 | 
					var TextFilters = map[string]TextFilter{
 | 
				
			||||||
 | 
						"upper-case": func(input string) (output string, err error) {
 | 
				
			||||||
 | 
							return strings.ToUpper(input), nil
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"lower-case": func(input string) (output string, err error) {
 | 
				
			||||||
 | 
							return strings.ToLower(input), nil
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	"unquote": func(input string) (output string, err error) {
 | 
						"unquote": func(input string) (output string, err error) {
 | 
				
			||||||
		return strconv.Unquote(input)
 | 
							return strconv.Unquote(input)
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"format-json": func(input string) (output string, err error) {
 | 
						"format-json": func(input string) (output string, err error) {
 | 
				
			||||||
		var dst bytes.Buffer
 | 
							var dst bytes.Buffer
 | 
				
			||||||
		if err := json.Indent(&dst, []byte(input), "", "  "); err != nil {
 | 
					
 | 
				
			||||||
			return "", err
 | 
							scnr := bufio.NewScanner(strings.NewReader(input))
 | 
				
			||||||
 | 
							for scnr.Scan() {
 | 
				
			||||||
 | 
								line := scnr.Text()
 | 
				
			||||||
 | 
								if err := json.Indent(&dst, []byte(line), "", "  "); err == nil {
 | 
				
			||||||
 | 
									dst.WriteString("\n")
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return "", err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return dst.String(), nil
 | 
							return dst.String(), nil
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						"lorem-ipsum": func(input string) (output string, err error) {
 | 
				
			||||||
 | 
							return "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " +
 | 
				
			||||||
 | 
								"incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " +
 | 
				
			||||||
 | 
								"exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
 | 
				
			||||||
 | 
								"dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. " +
 | 
				
			||||||
 | 
								"Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " +
 | 
				
			||||||
 | 
								"mollit anim id est laborum.", nil
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue