saulpw / visidata

A terminal spreadsheet multitool for discovering and arranging data
http://visidata.org
GNU General Public License v3.0
7.89k stars 280 forks source link

Feature request: Text-editing conveniences when editing a cell #2500

Open cool-RR opened 2 months ago

cool-RR commented 2 months ago

I often edit text in cells by pressing e. I'm annoyed by how basic the text-editing interface is. Here are a few things I'd want:

  1. Bind both Ctrl-Backpace and Alt-Backspace to delete a word.
  2. Bind both Ctrl-Delete and Alt-Delete (or Alt-D) to delete a word forward.
  3. More difficult: Allow selecting text by pressing Shift-Right, Shift-Left, and selecting whole words by pressing Shift-Ctrl-Right etc. Though then we'd have to think how the clipboard would work in that context.

Any other suggestions are appreciated.

midichef commented 2 months ago

You can edit the cell in a full-featured editor like vim/emacs by pressing e and then ^O. For such advanced needs, it's probably best. My request: can we make a command that does the equivalent of e and ^O, but with one keypress instead of two?

For your number 1, ^W does what you want, delete a word. It's not currently possible to change edit-cell keybindings.

Another feature request, it would be nice for to edit-cell let me click the mouse to move the cursor.

cool-RR commented 2 months ago

Thanks for the tips. Regarding that ^W binding, where is that written? Are there more such bindings?

midichef commented 2 months ago

The keybindings are described in the "Input Keystrokes Help" sidebar that comes up automatically when I press e.

For me, options.disp_help is set to the default value of 2.

cool-RR commented 2 months ago

I can't get that help menu to show. Could you take a screenshot of it? I wonder whether there are any other goodies in there.

On Tue, Aug 27, 2024 at 3:25 AM midichef @.***> wrote:

The keybindings are described in the "Input Keystrokes Help" sidebar that comes up automatically when I press e.

For me, options.disp_help is set to the default value of 2.

— Reply to this email directly, view it on GitHub https://github.com/saulpw/visidata/issues/2500#issuecomment-2311338146, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAN3STVP7BT7KHUFXN5US3ZTPBRHAVCNFSM6AAAAABNBLMPUKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJRGMZTQMJUGY . You are receiving this because you authored the thread.Message ID: @.***>

midichef commented 2 months ago

Here is a screenshot of the menu. Also, maybe you can see the menu if you edit a cell after running vd as vd -N, which ignores your .visidatarc. vd-input-help

sourissouriante commented 1 week ago

My request: can we make a command that does the equivalent of e and ^O, but with one keypress instead of two?

@midichef , I'm working with this:

@visidata.VisiData.api
def launchVim(vd, *args):
    with SuspendCurses():

        tmp_file = '/dev/shm/visidata_tmp.txt'

        c1 = ['echo'] + list(args)
        subprocess.run(c1, stdout=open(tmp_file, 'w'), text=True)

        c2 = ['/usr/bin/nvim', '-u', '/home/share/syst/config/nvim/init.vim', tmp_file]
        subprocess.run(c2, text=True)

        with open(tmp_file, 'r') as f:
            r1 = f.read().strip()

        return r1

Sheet.addCommand("^W", "open-vim", "cursorCol.setValues([cursorRow], vd.launchVim(sheet.cursorValue))", "edit cell in vim")

Hope it helps. Any improvements to my clunky code greatly appreciated.

midichef commented 3 days ago

@sourissouriante Thanks for getting this feature going!

This version of the open-vim command will have problems on cells with certain values:

  1. '-n' (i.e. the string displayed on screen as -n)
  2. ' string with leading and trailing spaces '
  3. None

The first value turns the subprocess.run() command into echo -n. That gives an empty string, which produces an empty file in your editor instead of a file containing -n. The second problem value loses the leading and trailing spaces, because of the strip().

We can fix these first two problems by reusing the existing command launchExternalEditor() that I see in editor.py: https://github.com/saulpw/visidata/blob/3e10140963a62a5f78fc6b60ebd2ac9264ef2772/visidata/_input.py#L252

The third problem is an error when editing a None cell: TypeError: expected str, bytes or os.PathLike object, not NoneType It happens when the None value in the cell is passed directly to subprocess.run(['echo', None], ...). To fix this, replace cursorValue with cursorDisplay.

cursorValue is a Python object for the contents of the cursor cell, and cursorDisplay is the string that is displayed for that value. For example, a cell with the number 1 has the cursorValue of 1 and a cursorDisplay of '1'. For a cell that holds None, its cursorValue is None, and cursorDisplay is the empty string ''. That empty string is what the editor should use.

Putting these fixes together gives this modified version of your command: BaseSheet.addCommand('ze', 'edit-cell-external', 'cursorCol.setValues([cursorRow], vd.launchExternalEditor(cursorDisplay))', 'edit current cell in $EDITOR')

In my opinion this useful command ought to be submitted in a pull request, putting it in sheets.py below the command for edit-cell. Would you like to submit a PR for it and list me as coauthor? Or vice versa?

saulpw commented 2 days ago

Thanks for the starting code, @sourissouriante, and to @midichef for some good cleanup. This would certainly be good to submit as a PR. A couple of notes to take into account:

  1. We use sysedit and sysopen as the verbs that use external tools.
  2. cursorCol.setValue (singular) should be sufficient for this case
  3. Ctrl+O may be a more consistent keybinding for this action, as it's already used on the DirSheet and in edit mode for the same purpose.
midichef commented 9 hours ago

Ah, right, that all makes sense. I like Ctrl+O as the keybinding for consistency.

saulpw commented 9 hours ago

Oh, and it should be on TableSheet.