UNPKG

jack-cli

Version:

Chop through that Git log wicked fast!

208 lines (170 loc) 5.04 kB
import { Action, ActionType, State } from '../types/types'; import { colors } from '../util/colors'; import { getBlacklistPatterns, getShowLineNumbers } from '../util/config-util'; import { getNextIndex, getPreviousIndex } from '../util/util-functions'; import { INITIAL_STATE } from './store'; const COMMIT_SHA_REGEX: RegExp = new RegExp(/[0-9a-f]{7,40}\b/); const blacklistPatterns: RegExp[] = getBlacklistPatterns(); const showLineNumbers = getShowLineNumbers(); export const reducer = ( state: State = INITIAL_STATE, action: Action, ): State => { if (action.type === ActionType.ADD_COMMITS) { const indexesWithSHAs = [...state.indexesWithSHAs]; const newLines = action.payload.map((line: string, i: number) => { if ( COMMIT_SHA_REGEX.test(line) && !blacklistPatterns.some((blacklistPattern) => blacklistPattern.test(line), ) ) { const indexWithLine = i + state.lines.length; indexesWithSHAs.push(indexWithLine); if (showLineNumbers) { return `${indexesWithSHAs.length}: ${line}`; } } return line; }); const lines = [...state.lines, ...newLines]; const visibleLines = [...state.visibleLines, ...newLines]; const index = indexesWithSHAs.includes(state.index) ? state.index : getNextIndex(indexesWithSHAs, state.index); return { ...state, SHA: state.SHA ? state.SHA : getSHA(lines[state.index], state.SHA), index, indexesWithSHAs, lines, visibleLines, }; } else if (action.type === ActionType.CLEAR_LOG) { return INITIAL_STATE; } else if (action.type === ActionType.MARK_SHA) { return { ...state, markedSHA: action.payload }; } else if (action.type === ActionType.NEXT_SEARCH_RESULT) { let { index, SHA } = state; const { indexesWithSHAs, indexesMatchingSearch, lines } = state; if (indexesMatchingSearch.length) { let searchResultIndex = getNextIndex( [...indexesMatchingSearch], index, ); if (!indexesWithSHAs.includes(searchResultIndex)) { const nextSHAIndex = getNextIndex([...indexesWithSHAs], index); if (searchResultIndex < nextSHAIndex) { searchResultIndex = getNextIndex( [...indexesMatchingSearch], searchResultIndex, ); } index = getPreviousIndex( [...indexesWithSHAs], searchResultIndex, ); } else { index = searchResultIndex; } SHA = getSHA(lines[index], SHA); } return { ...state, SHA, index, }; } else if (action.type === ActionType.PREVIOUS_SEARCH_RESULT) { let { index, SHA } = state; const { indexesWithSHAs, indexesMatchingSearch, lines } = state; if (indexesMatchingSearch.length) { const searchResultIndex = getPreviousIndex( [...indexesMatchingSearch], index, ); if (!indexesWithSHAs.includes(searchResultIndex)) { index = getPreviousIndex( [...indexesWithSHAs], searchResultIndex, ); } else { index = searchResultIndex; } SHA = getSHA(lines[index], SHA); } return { ...state, SHA, index, }; } else if (action.type === ActionType.UPDATE_SEARCH) { const indexesMatchingSearch: number[] = action.payload.indexesMatchingSearch; const searchTerm: string = action.payload.searchTerm; let { index, SHA } = state; const { indexesWithSHAs, lines } = state; const visibleLines: string[] = [...lines]; if (indexesMatchingSearch.length) { const searchRegex = new RegExp( searchTerm.replace(new RegExp(' ', 'g'), '.*?'), 'gi', ); indexesMatchingSearch.forEach((i) => { visibleLines[i] = visibleLines[i].replace( searchRegex, colors.searchHit, ); }); let searchResultIndex = index; if (!indexesMatchingSearch.includes(index)) { searchResultIndex = getNextIndex(indexesMatchingSearch, index); } if (!indexesWithSHAs.includes(searchResultIndex)) { index = getPreviousIndex( [...indexesWithSHAs], searchResultIndex, ); } else { index = searchResultIndex; } SHA = getSHA(lines[index], SHA); } return { ...state, SHA, index, indexesMatchingSearch, search: searchTerm, visibleLines, }; } else if (action.type === ActionType.UPDATE_INDEX) { const indexFn = action.payload > 0 ? getNextIndex : getPreviousIndex; let { index } = state; const { indexesWithSHAs } = state; for (let i = Math.abs(action.payload); i > 0; i--) { index = indexFn([...indexesWithSHAs], index); } return { ...state, SHA: getSHA(state.lines[index], state.SHA), index, }; } else if (action.type === ActionType.UPDATE_STATUS) { return { ...state, status: action.payload }; } else if (action.type === ActionType.UPDATE_VIEW) { return { ...state, view: action.payload }; } else { return state; } }; const getSHA = (lineText: string, defaultValue: string): string => { const matches: RegExpExecArray | null = COMMIT_SHA_REGEX.exec(lineText); if (!matches) { return defaultValue; } const matchedSHA: string | null = matches[0]; if (matchedSHA) { return matchedSHA; } return defaultValue; };