import React, { useEffect, useState } from "react"; import styled from "styled-components"; import { Button, buttonColor, defaultBorderRadius, secondaryDark } from "."; import { useSelector } from "react-redux"; import { selectDebugContext, selectAllRangesInFiles, selectRangesMask, } from "../redux/selectors/debugContextSelectors"; import "../highlight/dark.min.css"; import hljs from "highlight.js"; import { postVscMessage } from "../vscode"; import { RootStore } from "../redux/store"; import { useDispatch } from "react-redux"; import { addRangeInFile, deleteRangeInFileAt, toggleSelectionAt, updateFileSystem, } from "../redux/slices/debugContexSlice"; import { RangeInFile } from "../../../src/client"; import { readRangeInVirtualFileSystem } from "../util"; //#region Styled Components const MultiSelectContainer = styled.div` border-radius: ${defaultBorderRadius}; padding: 4px; display: flex; flex-direction: column; gap: 4px; `; const MultiSelectHeader = styled.div` display: flex; justify-content: space-between; align-items: left; border-bottom: 1px solid gray; padding-left: 4px; padding-right: 4px; & p { overflow-wrap: break-word; word-wrap: break-word; -ms-wrap-flow: break-word; overflow: hidden; } `; const MultiSelectOption = styled.div` border-radius: ${defaultBorderRadius}; padding-top: 4px; cursor: pointer; background-color: ${secondaryDark}; `; const DeleteSelectedRangeButton = styled(Button)` align-self: right; padding: 0px; margin-top: 0; aspect-ratio: 1/1; height: 28px; `; const ToggleHighlightButton = styled(Button)` display: grid; justify-content: center; align-items: center; grid-template-columns: 30px 1fr; margin-left: 20px; order: 1; width: fit-content; `; //#endregion //#region Path Formatting const filenameToLanguageMap: any = { py: "python", js: "javascript", ts: "typescript", html: "html", css: "css", java: "java", c: "c", cpp: "cpp", cs: "csharp", go: "go", rb: "ruby", rs: "rust", swift: "swift", php: "php", scala: "scala", kt: "kotlin", dart: "dart", hs: "haskell", lua: "lua", pl: "perl", r: "r", sql: "sql", vb: "vb", xml: "xml", yaml: "yaml", }; function filenameToLanguage(filename: string): string { const extension = filename.split(".").pop(); if (extension === undefined) { return ""; } return filenameToLanguageMap[extension] || ""; } function formatPathRelativeToWorkspace( path: string, workspacePath: string | undefined ) { if (workspacePath === undefined) { return path; } if (path.startsWith(workspacePath)) { return path.substring(workspacePath.length + 1); } else { return path; } } function formatFileRange( rangeInFile: RangeInFile, workspacePath: string | undefined ) { return `${formatPathRelativeToWorkspace( rangeInFile.filepath, workspacePath )} (lines ${rangeInFile.range.start.line + 1}-${ rangeInFile.range.end.line + 1 })`; // +1 because VS Code Ranges are 0-indexed } //#endregion function CodeMultiselect(props: {}) { // State const [highlightLocked, setHighlightLocked] = useState(true); // Redux const dispatch = useDispatch(); const workspacePath = useSelector( (state: RootStore) => state.config.workspacePath ); const debugContext = useSelector(selectDebugContext); const rangesInFiles = useSelector(selectAllRangesInFiles); const rangesInFilesMask = useSelector(selectRangesMask); useEffect(() => { let eventListener = (event: any) => { switch (event.data.type) { case "highlightedCode": if (!highlightLocked) { dispatch( addRangeInFile({ rangeInFile: event.data.rangeInFile, canUpdateLast: true, }) ); dispatch(updateFileSystem(event.data.filesystem)); } break; case "findSuspiciousCode": for (let c of event.data.codeLocations) { dispatch(addRangeInFile({ rangeInFile: c, canUpdateLast: false })); } dispatch(updateFileSystem(event.data.filesystem)); postVscMessage("listTenThings", { debugContext }); break; } }; window.addEventListener("message", eventListener); return () => window.removeEventListener("message", eventListener); }, [debugContext, highlightLocked]); useEffect(() => { hljs.highlightAll(); }, [rangesInFiles]); return ( {rangesInFiles.map((range: RangeInFile, index: number) => { return ( { dispatch(toggleSelectionAt(index)); }} >

{formatFileRange(range, workspacePath)}

dispatch(deleteRangeInFileAt(index))} > x
              
                {readRangeInVirtualFileSystem(range, debugContext.filesystem)}
              
            
); })} {rangesInFiles.length === 0 && ( <>

Highlight relevant code in the editor.

)} { setHighlightLocked(!highlightLocked); }} > {highlightLocked ? ( <> {" "} Enable Highlight ) : ( <> {" "} Disable Highlight )}
); } export default CodeMultiselect;