Skip to content

Commit

Permalink
[guide] add API for getting and adding guides
Browse files Browse the repository at this point in the history
- add vd.getGuide and vd.addGuide
- add a Macros guide as proof of concept
- add color_heading for markdown formatting
- change open-guide to open-guide-index
  • Loading branch information
anjakefala committed Nov 26, 2023
1 parent 3f9b77a commit c34ed42
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 9 deletions.
1 change: 1 addition & 0 deletions visidata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def getGlobals():
import visidata.textsheet
import visidata.threads
import visidata.path
import visidata.guide
import visidata._input
import visidata.tuiwin
Expand Down
1 change: 1 addition & 0 deletions visidata/cliptext.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ def clipdraw_chunks(scr, y, x, chunks, cattr:ColorAttr=ColorAttr(), w=None, clea
def _markdown_to_internal(text):
'Return markdown-formatted `text` converted to internal formatting (like `[:color]text[/]`).'
text = re.sub(r'`(.*?)`', r'[:code]\1[/]', text)
text = re.sub(r'(#.*?)$', r'[:heading]\1[/]', text)
text = re.sub(r'\*\*(.*?)\*\*', r'[:bold]\1[/]', text)
text = re.sub(r'\*(.*?)\*', r'[:italic]\1[/]', text)
text = re.sub(r'\b_(.*?)_\b', r'[:underline]\1[/]', text)
Expand Down
62 changes: 55 additions & 7 deletions visidata/experimental/guide.py → visidata/guide.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
'''
# A Guide to VisiData Guides
Each guide shows you how to use a particular feature in VisiData.
Each guide shows you how to use a particular feature in VisiData. Gray guides have not been written yet. We love contributions: [:onclick https://visidata.org/docs/guides]https://visidata.org/docs/guides[/].
[:keys]Up/Down[/] to move the row cursor
[:keys]Enter[/] to view a topic
[:keys]Backspace[/] to come back to this list of guides
- [:keystrokes]Up/Down[/] to move the row cursor
- [:keystrokes]Enter[/] to view a topic
- [:keystrokes]Backspace[/] to come back to this list of guides
'''

import re

from visidata import vd, BaseSheet, Sheet, ItemColumn, Column, VisiData
from visidata import vd, BaseSheet, Sheet, ItemColumn, Column, VisiData, ENTER, RowColorizer
from visidata import wraptext

vd.guides = {} # name -> guidecls

@VisiData.api
def addGuide(vd, name, guidecls):
vd.guides[name] = guidecls

@VisiData.api
class GuideGuide(Sheet):
help = __doc__
rowtype = 'guides' # rowdef: list(guide number, guide name, topic description, points, max_points)
columns = [
ItemColumn('n', 0, type=int),
ItemColumn('sheetname', 1, width=0),
ItemColumn('name', 1, width=0),
ItemColumn('topic', 2, width=60),
Column('points', type=int, getter=lambda c,r: 0),
Column('max_points', type=int, getter=lambda c,r: 100),
]
colorizers = [
RowColorizer(7, 'color_guide_unwritten', lambda s,c,r,v: r and r[1] not in vd.guides)
]
def iterload(self):
i = 0
for line in '''
Expand Down Expand Up @@ -86,4 +96,42 @@ def iterload(self):
yield [i] + list(m.groups())
i += 1

BaseSheet.addCommand('', 'open-guide', 'vd.push(GuideGuide("VisiData_Guide"))')
def openRow(self, row):
name = row[1]
return vd.getGuide(name)

class GuideSheet(Sheet):
rowtype = 'lines'
filetype = 'guide'
columns = [
ItemColumn('linenum', 0, type=int, width=0),
ItemColumn('guide', 1, width=80, displayer='full'),
]
precious = False
guide = ''

def iterload(self):
winWidth = 78
for startingLine, text in enumerate(self.guide.splitlines()):
text = text.strip()
if text:
for i, (L, _) in enumerate(wraptext(str(text), width=winWidth)):
yield [startingLine+i+1, L]
else:
yield [startingLine+1, text]



@VisiData.api
def getGuide(vd, name): # -> GuideSheet()
if name in vd.guides:
return vd.guides[name]()
vd.warning(f'no guide named {name}')

BaseSheet.addCommand('', 'open-guide-index', 'vd.push(GuideGuide("VisiData_Guide"))', 'open VisiData guides table of contents')

vd.addMenuItems('''
Help > VisiData Feature Guides > open-guide-index
''')

vd.addGlobals({'GuideSheet':GuideSheet})
2 changes: 2 additions & 0 deletions visidata/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
vd.theme_option('color_selected_row', '215 yellow', 'color of selected rows')
vd.theme_option('color_clickable', 'underline', 'color of internally clickable item')
vd.theme_option('color_code', 'bold white on 237', 'color of code sample')
vd.theme_option('color_heading', 'bold 200', 'color of header')
vd.theme_option('color_guide_unwritten', '243 on black', 'color of unwritten guides in GuideGuide')

vd.theme_option('force_256_colors', False, 'use 256 colors even if curses reports fewer')

Expand Down
26 changes: 24 additions & 2 deletions visidata/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from visidata.cmdlog import CommandLog, CommandLogJsonl
from visidata import vd, UNLOADED, asyncthread
from visidata import IndexSheet, VisiData, Sheet, Path, VisiDataMetaSheet, Column, ItemColumn, BaseSheet
from visidata import IndexSheet, VisiData, Sheet, Path, VisiDataMetaSheet, Column, ItemColumn, BaseSheet, GuideSheet

vd.macroMode = None
vd.macrobindings = {}
Expand Down Expand Up @@ -125,15 +125,37 @@ def startMacro(cmdlog):
vd.status("recording macro; stop recording with `m`")
vd.macroMode = CommandLogJsonl('current_macro', rows=[])


@VisiData.before
def run(vd, *args, **kwargs):
vd.macrosheet

class MacrosGuide(GuideSheet):
guide = '''# Macros
Macros allow you to bind a command sequence to a keystroke or longname, to replay when that keystroke is pressed or the command is executed by longname.
The basic usage is:
1. Press `m` (macro-record) to begin recording the macro.
2. Go through the commands you wish to record.
3. Then type `m` again to complete the recording, and prompt for the keystroke or longname to bind it to.
The macro will then be executed everytime the provided keystroke or longname are used. Note: the Alt+keys and the function keys are left unbound; overriding other keys may conflict with existing bindings, now or in the future.
Executing a macro will the series of commands starting on the current row and column on the current sheet.
# The Macros Sheet
Use `gm` (`macro-sheet`) to open an index of existing macros.
Use `d` to mark macros for deletion. Use `z Ctrl+S` to then commit any changes.
`Enter` to open the macro in the current row, and you can view the series of commands composing it.'''


Sheet.addCommand('m', 'macro-record', 'vd.cmdlog.startMacro()', 'record macro')
Sheet.addCommand('gm', 'macro-sheet', 'vd.push(vd.macrosheet)', 'open macros sheet')

vd.addMenuItems('''
System > Macros sheet > macro-sheet
''')

vd.addGuide('MacrosSheet', MacrosGuide)

0 comments on commit c34ed42

Please # to comment.