rp 0.1.1360__tar.gz → 0.1.1362__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rp-0.1.1360 → rp-0.1.1362}/PKG-INFO +1 -1
- rp-0.1.1362/rp/rp_ptpython/backslash_commands.py +633 -0
- rp-0.1.1362/rp/rp_ptpython/bash_extract.py +563 -0
- rp-0.1.1362/rp/rp_ptpython/bash_inline.py +439 -0
- rp-0.1.1362/rp/rp_ptpython/bash_rename.py +386 -0
- rp-0.1.1362/rp/version.py +1 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp.egg-info/PKG-INFO +1 -1
- {rp-0.1.1360 → rp-0.1.1362}/rp.egg-info/SOURCES.txt +4 -0
- rp-0.1.1362/version.py +1 -0
- rp-0.1.1360/rp/version.py +0 -1
- rp-0.1.1360/version.py +0 -1
- {rp-0.1.1360 → rp-0.1.1362}/.gitignore +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/QuickPython.iml +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/QuickPython.time +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/encodings.xml +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/inspectionProfiles/Project_Default.xml +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/misc.xml +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/modules.xml +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/vcs.xml +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.idea/workspace.xml +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.publish.sh.un~ +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.setup.py.un~ +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/.update_module_paths.py.un~ +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/LICENSE.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/README +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/Scrap +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/aoisdasd +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/increment_version.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/oijio +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/publish.sh +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/pyqtconsoletest.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/__main__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/documentation.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/Pyperclip.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/debug_comment.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/draw_code_minimap.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/graveyard.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/_compatibility.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/cache.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/file_io.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/grammar.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/normalizer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/parser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/pgen2/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/pgen2/generator.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/pgen2/grammar_parser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/diff.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/errors.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar26.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar27.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar310.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar311.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar312.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar33.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar34.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar35.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar36.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar37.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar38.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/grammar39.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/parser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/pep8.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/prefix.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/token.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/tokenize.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/python/tree.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/tree.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/parso/utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/peepdis/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/peepdis/core.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/peepdis/datastructures.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/peepdis/legacy.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/peepdis/preferences.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/powerpoint_converter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/profile_vim_plugins.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/bindings/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/bindings/flann_ctypes.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/exceptions.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/index.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/io/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/io/binary_dataset.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/io/dat_dataset.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/io/dataset.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/io/hdf5_dataset.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/io/npy_dataset.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/util/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyflann/util/weave_tools.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/__version__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/app.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/cli.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/cli_utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/config/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/config/config.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/config/config_error.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/config/config_parser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/config/config_transformer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/config/validators/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/config/validators/options.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/logging.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/autocomplete/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/autocomplete/autocomplete_listener.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/common/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/common/jsonpath/JSONPathLexer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/common/jsonpath/JSONPathListener.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/common/jsonpath/JSONPathParser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/common/jsonpath/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/io/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/io/datasource.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/model/model.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/service/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/service/client.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/service/dispatcher.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/common/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/common/popup.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/common/selectable_text.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/autocomplete_popup/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/autocomplete_popup/autocomplete_popup.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/autocomplete_popup/autocomplete_popup_keymapper.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/help_bar/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/help_bar/help_bar.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/help_page/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/help_page/detailed_help_page.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/json_browser/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/json_browser/json_browser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/json_browser/json_browser_keymapper.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/query_bar/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/query_bar/query_bar.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/components/query_bar/query_bar_keymapper.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/array/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/array/array_end_node.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/array/array_end_widget.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/array/array_node.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/array/array_start_widget.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/array/array_unexpanded_widget.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/json_composite_end_node.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/json_composite_node.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/json_listbox.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/json_listwalker.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/json_simple_node.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/json_widget.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/node_factory.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/object/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/object/object_end_node.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/object/object_end_widget.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/object/object_node.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/object/object_start_widget.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/object/object_unexpanded_widget.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/boolean.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/generic.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/integer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/null.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/numeric.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/primitive/string.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/json_lib/selector/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/keymapper/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/keymapper/abstract_component_keymapper.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/keymapper/keymapper.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/keymapper/keymapper_config.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/keymapper/keymapper_config_parser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/theme/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/theme/theme.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/theme/theme_config.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/theme/theme_config_parser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/view_config.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/view_frame.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pyfx/view/view_manager.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pynput_recorder.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pypi_inspection.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/pytorch_module_explorer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/refactor/string_format/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/refactor/string_format/format_to_fstring_converter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/refactor/string_format/fstring_converter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/refactor/string_format/test_format_to_fstring_converter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/refactor/string_format/test_fstring_converter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/rp_black_macchiato.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/stamp_tensor.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/stdin_python_highlighter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/__main__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/canvas.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/colors.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/console.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/funcs.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/nbinput.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/shapes.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/graphics/graphics/sprite.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/letters.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tetris/tetrisShapes.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/__main__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/argparser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/meta.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/methods/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/methods/ansi.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/methods/ansi_methods.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/methods/ascii.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/methods/method.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/methods/sixel.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/timg/renderer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/torch_hooks.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/torch_tools.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tracetraptest.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/tweenline.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/libs/webeval_dataset.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/list_of_modules.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/blm.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/chainsaw.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/death_of_the_mind.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/flappy.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/mario.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/matrix.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/mpi_untitled.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/py2048.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/pychess.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/rp_mpi.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/ryan_zshrc.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/shotgun.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/skia_trail_interactive_paint_demo.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/snake.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/sudoku.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/tetris.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/misc/trans.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/application.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/auto_suggest.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/buffer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/buffer_mapping.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/cache.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/clipboard/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/clipboard/base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/clipboard/in_memory.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/clipboard/pyperclip.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/completion.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/completers/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/completers/base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/completers/filesystem.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/completers/system.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/regular_languages/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/regular_languages/compiler.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/regular_languages/completion.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/regular_languages/lexer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/regular_languages/regex_parser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/regular_languages/validation.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/telnet/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/telnet/application.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/telnet/log.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/telnet/protocol.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/telnet/server.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/validators/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/contrib/validators/base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/document.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/enums.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/asyncio_base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/asyncio_posix.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/asyncio_win32.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/callbacks.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/inputhook.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/posix.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/posix_utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/select.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/eventloop/win32.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/filters/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/filters/base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/filters/cli.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/filters/types.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/filters/utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/history.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/input.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/interface.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/bindings/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/bindings/basic.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/bindings/completion.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/bindings/emacs.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/bindings/named_commands.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/bindings/scroll.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/bindings/vi.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/defaults.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/digraphs.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/input_processor.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/manager.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/registry.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/key_binding/vi_state.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/keys.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/containers.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/controls.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/dimension.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/lexers.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/margins.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/menus.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/mouse_handlers.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/processors.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/prompt.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/screen.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/toolbars.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/untitled.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/layout/utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/mouse_events.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/output.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/reactive.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/renderer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/search_state.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/selection.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/shortcuts.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/styles/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/styles/base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/styles/defaults.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/styles/from_dict.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/styles/from_pygments.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/styles/utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/terminal/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/terminal/conemu_output.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/terminal/vt100_input.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/terminal/vt100_output.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/terminal/win32_input.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/terminal/win32_output.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/token.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/validation.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/prompt_toolkit/win32_types.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/r.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/__main__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/ast_selection.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/async_analyzer_base.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/async_jedi_highlighter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/bash_completer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/bash_selection.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/completer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/completer_old.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/completion_ranker.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/completion_schema.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/completion_types.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/eventloop.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/filters.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/history_browser.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/ipython.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/jedi_highlighter.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/jedi_lexer.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/jedi_utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/key_bindings.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/layout.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/patch_linecache.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/path_completer_utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/prompt_style.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/python_input.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/r_iterm_comm.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/refactor_extract.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/refactor_inline.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/refactor_move.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/refactor_move_bash.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/refactor_rename.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/repl.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/__init__.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/commands.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/completers.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/completion_hints.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/grammar.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/key_bindings.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/layout.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/style.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/rp_ptpdb/toolbars.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/selection_utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/style.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/testable_keybindings.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/treesitter_selection.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/treesitter_semantic.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/unreachable_detector.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/utils.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/rp_ptpython/validator.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/ryan_vimrc.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp/web_evaluator.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp.egg-info/dependency_links.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp.egg-info/entry_points.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp.egg-info/requires.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/rp.egg-info/top_level.txt +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/setup.cfg +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/setup.py +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/untitled.c +0 -0
- {rp-0.1.1360 → rp-0.1.1362}/update_module_paths.py +0 -0
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Backslash Commands Module
|
|
3
|
+
|
|
4
|
+
Provides a command mode for applying text transformations to selections.
|
|
5
|
+
When text is selected and \ is pressed, enters command mode where you can
|
|
6
|
+
type a command name and press Enter to apply it to the selection.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
1. Select some text
|
|
10
|
+
2. Press \
|
|
11
|
+
3. Type command name (e.g., 'rl' for reverse_lines)
|
|
12
|
+
4. Press Enter to apply, Escape to cancel
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
Select: line3 After \rl: line1
|
|
16
|
+
line2 line2
|
|
17
|
+
line1 line3
|
|
18
|
+
"""
|
|
19
|
+
from typing import Callable, Dict, Tuple, Optional
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# =============================================================================
|
|
23
|
+
# COMMAND REGISTRY
|
|
24
|
+
# =============================================================================
|
|
25
|
+
|
|
26
|
+
# Commands are {shortcut: (full_name, description, transform_fn)}
|
|
27
|
+
# transform_fn takes text and returns transformed text
|
|
28
|
+
COMMANDS: Dict[str, Tuple[str, str, Callable[[str], str]]] = {}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def register(shortcut: str, name: str, description: str):
|
|
32
|
+
"""Decorator to register a backslash command."""
|
|
33
|
+
def decorator(fn: Callable[[str], str]):
|
|
34
|
+
COMMANDS[shortcut] = (name, description, fn)
|
|
35
|
+
return fn
|
|
36
|
+
return decorator
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# =============================================================================
|
|
40
|
+
# BUILT-IN COMMANDS
|
|
41
|
+
# =============================================================================
|
|
42
|
+
|
|
43
|
+
@register('rl', 'reverse_lines', 'Reverse line order')
|
|
44
|
+
def reverse_lines(text: str) -> str:
|
|
45
|
+
# a\n b\n c -> c\n b\n a
|
|
46
|
+
return '\n'.join(reversed(text.split('\n')))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@register('sl', 'sort_lines', 'Sort lines alphabetically')
|
|
50
|
+
def sort_lines(text: str) -> str:
|
|
51
|
+
# c\n a\n b -> a\n b\n c
|
|
52
|
+
return '\n'.join(sorted(text.split('\n')))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@register('slu', 'sort_lines_unique', 'Sort lines and remove duplicates')
|
|
56
|
+
def sort_lines_unique(text: str) -> str:
|
|
57
|
+
# b\n a\n b -> a\n b
|
|
58
|
+
return '\n'.join(sorted(set(text.split('\n'))))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@register('u', 'unique', 'Remove duplicate lines (preserve order)')
|
|
62
|
+
def unique_lines(text: str) -> str:
|
|
63
|
+
# a\n b\n a -> a\n b
|
|
64
|
+
seen = set()
|
|
65
|
+
result = []
|
|
66
|
+
for line in text.split('\n'):
|
|
67
|
+
if line not in seen:
|
|
68
|
+
seen.add(line)
|
|
69
|
+
result.append(line)
|
|
70
|
+
return '\n'.join(result)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@register('uc', 'upper', 'Convert to UPPERCASE')
|
|
74
|
+
def upper(text: str) -> str:
|
|
75
|
+
return text.upper()
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@register('lc', 'lower', 'Convert to lowercase')
|
|
79
|
+
def lower(text: str) -> str:
|
|
80
|
+
return text.lower()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@register('tc', 'title', 'Convert To Title Case')
|
|
84
|
+
def title(text: str) -> str:
|
|
85
|
+
return text.title()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@register('stp', 'strip', 'Strip leading/trailing whitespace')
|
|
89
|
+
def strip(text: str) -> str:
|
|
90
|
+
return text.strip()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@register('stpl', 'strip_lines', 'Strip each line')
|
|
94
|
+
def strip_lines(text: str) -> str:
|
|
95
|
+
return '\n'.join(line.strip() for line in text.split('\n'))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@register('ind', 'indent', 'Indent by 4 spaces')
|
|
99
|
+
def indent(text: str) -> str:
|
|
100
|
+
return '\n'.join(' ' + line for line in text.split('\n'))
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@register('ded', 'dedent', 'Remove one level of indentation')
|
|
104
|
+
def dedent(text: str) -> str:
|
|
105
|
+
lines = text.split('\n')
|
|
106
|
+
result = []
|
|
107
|
+
for line in lines:
|
|
108
|
+
if line.startswith(' '):
|
|
109
|
+
result.append(line[4:])
|
|
110
|
+
elif line.startswith('\t'):
|
|
111
|
+
result.append(line[1:])
|
|
112
|
+
else:
|
|
113
|
+
result.append(line)
|
|
114
|
+
return '\n'.join(result)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@register('rev', 'reverse', 'Reverse text')
|
|
118
|
+
def reverse_text(text: str) -> str:
|
|
119
|
+
# abc -> cba
|
|
120
|
+
return text[::-1]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@register('sq', 'squeeze', 'Squeeze multiple blank lines to one')
|
|
124
|
+
def squeeze(text: str) -> str:
|
|
125
|
+
import re
|
|
126
|
+
return re.sub(r'\n{3,}', '\n\n', text)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
@register('nb', 'no_blanks', 'Remove blank lines')
|
|
130
|
+
def no_blanks(text: str) -> str:
|
|
131
|
+
return '\n'.join(line for line in text.split('\n') if line.strip())
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@register('num', 'number', 'Add line numbers')
|
|
135
|
+
def number_lines(text: str) -> str:
|
|
136
|
+
# a\n b -> 1: a\n 2: b
|
|
137
|
+
lines = text.split('\n')
|
|
138
|
+
width = len(str(len(lines)))
|
|
139
|
+
return '\n'.join(f'{i+1:>{width}}: {line}' for i, line in enumerate(lines))
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@register('unnum', 'unnumber', 'Remove line numbers')
|
|
143
|
+
def unnumber_lines(text: str) -> str:
|
|
144
|
+
# 1: a\n 2: b -> a\n b
|
|
145
|
+
import re
|
|
146
|
+
return '\n'.join(re.sub(r'^\s*\d+:\s?', '', line) for line in text.split('\n'))
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@register('j', 'join', 'Join lines with space')
|
|
150
|
+
def join_lines(text: str) -> str:
|
|
151
|
+
# a\n b\n c -> a b c
|
|
152
|
+
return ' '.join(text.split('\n'))
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@register('jc', 'join_comma', 'Join lines with comma')
|
|
156
|
+
def join_comma(text: str) -> str:
|
|
157
|
+
# a\n b\n c -> a, b, c
|
|
158
|
+
return ', '.join(line.strip() for line in text.split('\n') if line.strip())
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@register('sp', 'split', 'Split on spaces to lines')
|
|
162
|
+
def split_spaces(text: str) -> str:
|
|
163
|
+
# a b c -> a\n b\n c
|
|
164
|
+
return '\n'.join(text.split())
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@register('spc', 'split_comma', 'Split on commas to lines')
|
|
168
|
+
def split_comma(text: str) -> str:
|
|
169
|
+
# a, b, c -> a\n b\n c
|
|
170
|
+
return '\n'.join(part.strip() for part in text.split(','))
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
@register('q', 'quote', 'Quote each line')
|
|
174
|
+
def quote_lines(text: str) -> str:
|
|
175
|
+
# a\n b -> "a"\n "b"
|
|
176
|
+
return '\n'.join(f'"{line}"' for line in text.split('\n'))
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@register('uq', 'unquote', 'Remove quotes from each line')
|
|
180
|
+
def unquote_lines(text: str) -> str:
|
|
181
|
+
# "a"\n 'b' -> a\n b
|
|
182
|
+
lines = []
|
|
183
|
+
for line in text.split('\n'):
|
|
184
|
+
s = line.strip()
|
|
185
|
+
if (s.startswith('"') and s.endswith('"')) or (s.startswith("'") and s.endswith("'")):
|
|
186
|
+
lines.append(s[1:-1])
|
|
187
|
+
else:
|
|
188
|
+
lines.append(line)
|
|
189
|
+
return '\n'.join(lines)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@register('c', 'comment', 'Comment lines with #')
|
|
193
|
+
def comment_lines(text: str) -> str:
|
|
194
|
+
# a\n b -> # a\n # b
|
|
195
|
+
return '\n'.join('# ' + line for line in text.split('\n'))
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@register('unc', 'uncomment', 'Remove # comments')
|
|
199
|
+
def uncomment_lines(text: str) -> str:
|
|
200
|
+
# # a\n # b -> a\n b
|
|
201
|
+
import re
|
|
202
|
+
return '\n'.join(re.sub(r'^(\s*)#\s?', r'\1', line) for line in text.split('\n'))
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@register('len', 'length', 'Show length of text')
|
|
206
|
+
def show_length(text: str) -> str:
|
|
207
|
+
lines = text.split('\n')
|
|
208
|
+
return f"[{len(text)} chars, {len(lines)} lines]"
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
# =============================================================================
|
|
212
|
+
# COMMANDS USING RP MODULE
|
|
213
|
+
# =============================================================================
|
|
214
|
+
|
|
215
|
+
@register('min', 'minify', 'Minify Python code')
|
|
216
|
+
def minify(text: str) -> str:
|
|
217
|
+
import rp
|
|
218
|
+
return rp.minify_python_code(text)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@register('bla', 'black', 'Format with black')
|
|
222
|
+
def black_format(text: str) -> str:
|
|
223
|
+
import rp
|
|
224
|
+
return rp.autoformat_code(text)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
@register('sc', 'strip_comments', 'Strip Python comments')
|
|
228
|
+
def strip_comments(text: str) -> str:
|
|
229
|
+
from rp import strip_python_comments
|
|
230
|
+
return strip_python_comments(text)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@register('sdo', 'strip_docstrings', 'Strip Python docstrings')
|
|
234
|
+
def strip_docstrings(text: str) -> str:
|
|
235
|
+
from rp import strip_python_docstrings
|
|
236
|
+
return strip_python_docstrings(text)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
@register('sim', 'sort_imports', 'Sort imports with isort')
|
|
240
|
+
def sort_imports(text: str) -> str:
|
|
241
|
+
import rp
|
|
242
|
+
return rp.isort(text)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@register('al', 'align', 'Align lines on = or :')
|
|
246
|
+
def align_lines(text: str) -> str:
|
|
247
|
+
import rp
|
|
248
|
+
return rp.align_lines(text)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@register('und', 'unindent', 'Remove common leading indentation')
|
|
252
|
+
def unindent(text: str) -> str:
|
|
253
|
+
import rp
|
|
254
|
+
return rp.unindent(text)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
@register('tts', 'tabs_to_spaces', 'Convert tabs to 4 spaces')
|
|
258
|
+
def tabs_to_spaces(text: str) -> str:
|
|
259
|
+
return text.replace('\t', ' ')
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
@register('cim', 'clean_imports', 'Clean/organize imports')
|
|
263
|
+
def clean_imports(text: str) -> str:
|
|
264
|
+
import rp
|
|
265
|
+
return rp.clean_imports(text)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@register('rms', 'remove_star', 'Expand star imports')
|
|
269
|
+
def remove_star(text: str) -> str:
|
|
270
|
+
import rp
|
|
271
|
+
return rp.remove_star_imports(text)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
@register('rmfs', 'remove_fstrings', 'Convert f-strings to .format()')
|
|
275
|
+
def remove_fstrings(text: str) -> str:
|
|
276
|
+
import rp
|
|
277
|
+
return rp.remove_fstrings(text)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@register('sw', 'strip_whitespace', 'Strip trailing whitespace from lines')
|
|
281
|
+
def strip_whitespace(text: str) -> str:
|
|
282
|
+
return '\n'.join(line.rstrip() for line in text.split('\n'))
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
@register('sbl', 'strip_blank_lines', 'Remove blank lines')
|
|
286
|
+
def strip_blank_lines(text: str) -> str:
|
|
287
|
+
from rp import strip_blank_lines
|
|
288
|
+
return strip_blank_lines(text)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
@register('mla', 'multi_line_args', 'Split function args to multiple lines')
|
|
292
|
+
def multi_line_args(text: str) -> str:
|
|
293
|
+
import rp
|
|
294
|
+
return rp.multi_line_args(text)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
@register('fi', 'from_import_swap', 'Swap import/from import style')
|
|
298
|
+
def from_import_swap(text: str) -> str:
|
|
299
|
+
import rp
|
|
300
|
+
return rp.import_from_swap(text)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
@register('ya', 'yapf', 'Format with yapf')
|
|
304
|
+
def yapf_format(text: str) -> str:
|
|
305
|
+
import rp
|
|
306
|
+
return rp.yapf_format(text)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
@register('23p', 'python2to3', 'Convert Python 2 to 3')
|
|
310
|
+
def python_2_to_3(text: str) -> str:
|
|
311
|
+
import rp
|
|
312
|
+
return rp.python_2_to_3(text)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
@register('rcl', 'reverse_columns', 'Reverse columns in each line')
|
|
316
|
+
def reverse_columns(text: str) -> str:
|
|
317
|
+
import rp
|
|
318
|
+
return rp.reverse_columns(text)
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
@register('spl', 'splitlines', 'Split into lines (normalize newlines)')
|
|
322
|
+
def splitlines(text: str) -> str:
|
|
323
|
+
return '\n'.join(text.splitlines())
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
@register('lj', 'line_join', 'Join lines with backslash continuation')
|
|
327
|
+
def line_join(text: str) -> str:
|
|
328
|
+
lines = text.split('\n')
|
|
329
|
+
return ' \\\n'.join(lines)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
@register('irp', 'inline_rp', 'Inline rp.* calls')
|
|
333
|
+
def inline_rp(text: str) -> str:
|
|
334
|
+
import rp
|
|
335
|
+
return rp.inline_rp(text)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
@register('qrp', 'qualify_rp', 'Qualify rp.* calls')
|
|
339
|
+
def qualify_rp(text: str) -> str:
|
|
340
|
+
import rp
|
|
341
|
+
return rp.qualify_rp(text)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
@register('rpr', 'repr', 'Wrap in repr()')
|
|
345
|
+
def wrap_repr(text: str) -> str:
|
|
346
|
+
return repr(text)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
@register('tbp', 'toggle_parens', 'Toggle big parenthesis style')
|
|
350
|
+
def toggle_big_parens(text: str) -> str:
|
|
351
|
+
import rp
|
|
352
|
+
return rp.toggle_big_parenthesis(text)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
@register('en', 'enumerate', 'Wrap iterable in enumerate()')
|
|
356
|
+
def wrap_enumerate(text: str) -> str:
|
|
357
|
+
return f'enumerate({text.strip()})'
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
@register('ac', 'align_char', 'Align on specific character')
|
|
361
|
+
def align_char(text: str) -> str:
|
|
362
|
+
import rp
|
|
363
|
+
return rp.align_char(text)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
# Delete empty lines variants
|
|
367
|
+
@register('d0l', 'del_empty_0', 'Delete lines with 0+ spaces only')
|
|
368
|
+
def del_empty_0(text: str) -> str:
|
|
369
|
+
return '\n'.join(l for l in text.split('\n') if l.strip())
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
@register('d1l', 'del_empty_1', 'Delete lines with <=1 char')
|
|
373
|
+
def del_empty_1(text: str) -> str:
|
|
374
|
+
return '\n'.join(l for l in text.split('\n') if len(l.strip()) > 1)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
@register('d2l', 'del_empty_2', 'Delete lines with <=2 chars')
|
|
378
|
+
def del_empty_2(text: str) -> str:
|
|
379
|
+
return '\n'.join(l for l in text.split('\n') if len(l.strip()) > 2)
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
# =============================================================================
|
|
383
|
+
# WRAP IN CONTROL STRUCTURES
|
|
384
|
+
# =============================================================================
|
|
385
|
+
|
|
386
|
+
@register('fo', 'for', 'Wrap in for loop')
|
|
387
|
+
def wrap_for(text: str) -> str:
|
|
388
|
+
# x -> for i in x:
|
|
389
|
+
# pass
|
|
390
|
+
import rp
|
|
391
|
+
indent = rp.get_indent(text) if '\n' in text else ''
|
|
392
|
+
return f'{indent}for i in {text.strip()}:\n{indent} pass'
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
@register('de', 'def', 'Wrap in function def')
|
|
396
|
+
def wrap_def(text: str) -> str:
|
|
397
|
+
# code -> def func():
|
|
398
|
+
# code
|
|
399
|
+
import rp
|
|
400
|
+
indented = rp.indent(text, ' ')
|
|
401
|
+
return f'def func():\n{indented}'
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
@register('wh', 'while', 'Wrap in while loop')
|
|
405
|
+
def wrap_while(text: str) -> str:
|
|
406
|
+
# cond -> while cond:
|
|
407
|
+
# pass
|
|
408
|
+
import rp
|
|
409
|
+
indent = rp.get_indent(text) if '\n' in text else ''
|
|
410
|
+
return f'{indent}while {text.strip()}:\n{indent} pass'
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
@register('wi', 'with', 'Wrap in with statement')
|
|
414
|
+
def wrap_with(text: str) -> str:
|
|
415
|
+
# expr -> with expr:
|
|
416
|
+
# pass
|
|
417
|
+
import rp
|
|
418
|
+
indent = rp.get_indent(text) if '\n' in text else ''
|
|
419
|
+
return f'{indent}with {text.strip()}:\n{indent} pass'
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
@register('if', 'if', 'Wrap in if statement')
|
|
423
|
+
def wrap_if(text: str) -> str:
|
|
424
|
+
# cond -> if cond:
|
|
425
|
+
# pass
|
|
426
|
+
import rp
|
|
427
|
+
indent = rp.get_indent(text) if '\n' in text else ''
|
|
428
|
+
return f'{indent}if {text.strip()}:\n{indent} pass'
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
@register('try', 'try', 'Wrap in try/except')
|
|
432
|
+
def wrap_try(text: str) -> str:
|
|
433
|
+
# code -> try:
|
|
434
|
+
# code
|
|
435
|
+
# except Exception as e:
|
|
436
|
+
# raise
|
|
437
|
+
import rp
|
|
438
|
+
indented = rp.indent(text, ' ')
|
|
439
|
+
return f'try:\n{indented}\nexcept Exception as e:\n raise'
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
@register('cl', 'class', 'Wrap in class def')
|
|
443
|
+
def wrap_class(text: str) -> str:
|
|
444
|
+
# code -> class MyClass:
|
|
445
|
+
# code
|
|
446
|
+
import rp
|
|
447
|
+
indented = rp.indent(text, ' ')
|
|
448
|
+
return f'class MyClass:\n{indented}'
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
@register('lam', 'lambda', 'Wrap in lambda')
|
|
452
|
+
def wrap_lambda(text: str) -> str:
|
|
453
|
+
# expr -> lambda: expr
|
|
454
|
+
return f'lambda: {text.strip()}'
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
@register('ret', 'return', 'Wrap in return')
|
|
458
|
+
def wrap_return(text: str) -> str:
|
|
459
|
+
# expr -> return expr
|
|
460
|
+
return f'return {text.strip()}'
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
@register('pr', 'print', 'Wrap in print()')
|
|
464
|
+
def wrap_print(text: str) -> str:
|
|
465
|
+
# expr -> print(expr)
|
|
466
|
+
return f'print({text.strip()})'
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
@register('li', 'list', 'Wrap in list()')
|
|
470
|
+
def wrap_list(text: str) -> str:
|
|
471
|
+
return f'list({text.strip()})'
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
@register('tu', 'tuple', 'Wrap in tuple()')
|
|
475
|
+
def wrap_tuple(text: str) -> str:
|
|
476
|
+
return f'tuple({text.strip()})'
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
@register('se', 'set', 'Wrap in set()')
|
|
480
|
+
def wrap_set(text: str) -> str:
|
|
481
|
+
return f'set({text.strip()})'
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
@register('di', 'dict', 'Wrap in dict()')
|
|
485
|
+
def wrap_dict(text: str) -> str:
|
|
486
|
+
return f'dict({text.strip()})'
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
@register('so', 'sorted', 'Wrap in sorted()')
|
|
490
|
+
def wrap_sorted(text: str) -> str:
|
|
491
|
+
return f'sorted({text.strip()})'
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
@register('le', 'len', 'Wrap in len()')
|
|
495
|
+
def wrap_len(text: str) -> str:
|
|
496
|
+
return f'len({text.strip()})'
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
@register('str', 'str', 'Wrap in str()')
|
|
500
|
+
def wrap_str(text: str) -> str:
|
|
501
|
+
return f'str({text.strip()})'
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
@register('int', 'int', 'Wrap in int()')
|
|
505
|
+
def wrap_int(text: str) -> str:
|
|
506
|
+
return f'int({text.strip()})'
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
@register('not', 'not', 'Wrap in not')
|
|
510
|
+
def wrap_not(text: str) -> str:
|
|
511
|
+
return f'not {text.strip()}'
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
@register('as', 'assert', 'Wrap in assert')
|
|
515
|
+
def wrap_assert(text: str) -> str:
|
|
516
|
+
return f'assert {text.strip()}'
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
# =============================================================================
|
|
520
|
+
# STATE CLASS
|
|
521
|
+
# =============================================================================
|
|
522
|
+
|
|
523
|
+
class BackslashCommandState:
|
|
524
|
+
"""State for backslash command input mode."""
|
|
525
|
+
|
|
526
|
+
def __init__(self):
|
|
527
|
+
self.reset()
|
|
528
|
+
|
|
529
|
+
def reset(self):
|
|
530
|
+
self.active = False
|
|
531
|
+
self.command = "" # Command being typed
|
|
532
|
+
self.cursor = 0 # Cursor position in command
|
|
533
|
+
self.error = None
|
|
534
|
+
self.original_code = "" # Full buffer before
|
|
535
|
+
self.selection_start = 0
|
|
536
|
+
self.selection_end = 0
|
|
537
|
+
self.selected_text = ""
|
|
538
|
+
|
|
539
|
+
def start(self, original_code: str, selection_start: int, selection_end: int):
|
|
540
|
+
"""Start command mode with selection."""
|
|
541
|
+
self.active = True
|
|
542
|
+
self.command = ""
|
|
543
|
+
self.cursor = 0
|
|
544
|
+
self.error = None
|
|
545
|
+
self.original_code = original_code
|
|
546
|
+
self.selection_start = selection_start
|
|
547
|
+
self.selection_end = selection_end
|
|
548
|
+
self.selected_text = original_code[selection_start:selection_end]
|
|
549
|
+
|
|
550
|
+
def add_char(self, char: str):
|
|
551
|
+
self.command = self.command[:self.cursor] + char + self.command[self.cursor:]
|
|
552
|
+
self.cursor += 1
|
|
553
|
+
|
|
554
|
+
def delete_char(self):
|
|
555
|
+
if self.cursor > 0:
|
|
556
|
+
self.command = self.command[:self.cursor-1] + self.command[self.cursor:]
|
|
557
|
+
self.cursor -= 1
|
|
558
|
+
|
|
559
|
+
def cursor_left(self):
|
|
560
|
+
if self.cursor > 0:
|
|
561
|
+
self.cursor -= 1
|
|
562
|
+
|
|
563
|
+
def cursor_right(self):
|
|
564
|
+
if self.cursor < len(self.command):
|
|
565
|
+
self.cursor += 1
|
|
566
|
+
|
|
567
|
+
def delete_forward(self):
|
|
568
|
+
if self.cursor < len(self.command):
|
|
569
|
+
self.command = self.command[:self.cursor] + self.command[self.cursor+1:]
|
|
570
|
+
|
|
571
|
+
def get_matching_commands(self) -> list:
|
|
572
|
+
"""Get commands that match current input."""
|
|
573
|
+
if not self.command:
|
|
574
|
+
return list(COMMANDS.keys())
|
|
575
|
+
return [k for k in COMMANDS if k.startswith(self.command)]
|
|
576
|
+
|
|
577
|
+
def get_preview(self) -> Optional[Tuple[str, int]]:
|
|
578
|
+
"""Get preview of transformation. Returns (new_full_code, cursor_pos) or None."""
|
|
579
|
+
if not self.active or not self.command:
|
|
580
|
+
return None
|
|
581
|
+
|
|
582
|
+
if self.command not in COMMANDS:
|
|
583
|
+
return None
|
|
584
|
+
|
|
585
|
+
_, _, transform_fn = COMMANDS[self.command]
|
|
586
|
+
try:
|
|
587
|
+
transformed = transform_fn(self.selected_text)
|
|
588
|
+
new_code = (self.original_code[:self.selection_start] +
|
|
589
|
+
transformed +
|
|
590
|
+
self.original_code[self.selection_end:])
|
|
591
|
+
new_cursor = self.selection_start + len(transformed)
|
|
592
|
+
return (new_code, new_cursor)
|
|
593
|
+
except Exception:
|
|
594
|
+
return None
|
|
595
|
+
|
|
596
|
+
def execute(self) -> Optional[Tuple[str, int]]:
|
|
597
|
+
"""Execute the command. Returns (new_code, cursor_pos) or None."""
|
|
598
|
+
return self.get_preview()
|
|
599
|
+
|
|
600
|
+
def get_status(self) -> str:
|
|
601
|
+
"""Get status line text."""
|
|
602
|
+
if self.error:
|
|
603
|
+
return f"\\{self.command}: {self.error}"
|
|
604
|
+
|
|
605
|
+
matches = self.get_matching_commands()
|
|
606
|
+
if not self.command:
|
|
607
|
+
hint = "Type command (Tab for list)"
|
|
608
|
+
elif len(matches) == 0:
|
|
609
|
+
hint = "No matching command"
|
|
610
|
+
elif len(matches) == 1 and matches[0] == self.command:
|
|
611
|
+
name, desc, _ = COMMANDS[self.command]
|
|
612
|
+
hint = f"{name}: {desc}"
|
|
613
|
+
else:
|
|
614
|
+
hint = ', '.join(matches[:5])
|
|
615
|
+
if len(matches) > 5:
|
|
616
|
+
hint += f'... (+{len(matches)-5})'
|
|
617
|
+
|
|
618
|
+
# Show cursor in command
|
|
619
|
+
cmd_display = self.command[:self.cursor] + '|' + self.command[self.cursor:]
|
|
620
|
+
return f"\\{cmd_display} [{hint}]"
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
# Global state instance
|
|
624
|
+
state = BackslashCommandState()
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
def get_all_commands() -> str:
|
|
628
|
+
"""Return formatted list of all commands for help."""
|
|
629
|
+
lines = ["Backslash Commands (select text, press \\, type command, Enter):"]
|
|
630
|
+
for shortcut in sorted(COMMANDS.keys()):
|
|
631
|
+
name, desc, _ = COMMANDS[shortcut]
|
|
632
|
+
lines.append(f" \\{shortcut:<6} {name:<20} {desc}")
|
|
633
|
+
return '\n'.join(lines)
|