2016-10-03 18:00:50 -08:00
|
|
|
import rpc from '../rpc';
|
|
|
|
|
import {
|
|
|
|
|
DIRECTION,
|
|
|
|
|
TERM_GROUP_RESIZE,
|
|
|
|
|
TERM_GROUP_REQUEST,
|
|
|
|
|
TERM_GROUP_EXIT,
|
|
|
|
|
TERM_GROUP_EXIT_ACTIVE
|
|
|
|
|
} from '../constants/term-groups';
|
|
|
|
|
import {SESSION_REQUEST} from '../constants/sessions';
|
2016-10-25 04:53:15 -08:00
|
|
|
import findBySession from '../utils/term-groups';
|
|
|
|
|
import getRootGroups from '../selectors';
|
2016-10-03 18:00:50 -08:00
|
|
|
import {setActiveSession, ptyExitSession, userExitSession} from './sessions';
|
|
|
|
|
|
|
|
|
|
function requestSplit(direction) {
|
2019-10-14 16:09:30 -08:00
|
|
|
return activeUid => (dispatch, getState) => {
|
2016-10-03 18:00:50 -08:00
|
|
|
dispatch({
|
|
|
|
|
type: SESSION_REQUEST,
|
|
|
|
|
effect: () => {
|
2019-10-14 16:09:30 -08:00
|
|
|
const {ui, sessions} = getState();
|
2016-10-03 18:00:50 -08:00
|
|
|
rpc.emit('new', {
|
|
|
|
|
splitDirection: direction,
|
2019-10-14 16:09:30 -08:00
|
|
|
cwd: ui.cwd,
|
|
|
|
|
activeUid: activeUid ? activeUid : sessions.activeUid
|
2016-10-03 18:00:50 -08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const requestVerticalSplit = requestSplit(DIRECTION.VERTICAL);
|
|
|
|
|
export const requestHorizontalSplit = requestSplit(DIRECTION.HORIZONTAL);
|
|
|
|
|
|
|
|
|
|
export function resizeTermGroup(uid, sizes) {
|
|
|
|
|
return {
|
|
|
|
|
uid,
|
|
|
|
|
type: TERM_GROUP_RESIZE,
|
|
|
|
|
sizes
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-14 16:09:30 -08:00
|
|
|
export function requestTermGroup(activeUid) {
|
2016-10-03 18:00:50 -08:00
|
|
|
return (dispatch, getState) => {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: TERM_GROUP_REQUEST,
|
|
|
|
|
effect: () => {
|
2018-03-21 03:40:56 -08:00
|
|
|
const {ui} = getState();
|
2019-10-10 11:20:26 -08:00
|
|
|
const {cwd} = ui;
|
2016-10-03 18:00:50 -08:00
|
|
|
rpc.emit('new', {
|
|
|
|
|
isNewGroup: true,
|
2019-10-14 16:09:30 -08:00
|
|
|
cwd,
|
|
|
|
|
activeUid
|
2016-10-03 18:00:50 -08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function setActiveGroup(uid) {
|
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
|
const {termGroups} = getState();
|
|
|
|
|
dispatch(setActiveSession(termGroups.activeSessions[uid]));
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When we've found the next group which we want to
|
|
|
|
|
// set as active (after closing something), we also need
|
|
|
|
|
// to find the first child group which has a sessionUid.
|
|
|
|
|
const findFirstSession = (state, group) => {
|
|
|
|
|
if (group.sessionUid) {
|
|
|
|
|
return group.sessionUid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const childUid of group.children) {
|
|
|
|
|
const child = state.termGroups[childUid];
|
|
|
|
|
// We want to find the *leftmost* session,
|
|
|
|
|
// even if it's nested deep down:
|
|
|
|
|
const sessionUid = findFirstSession(state, child);
|
|
|
|
|
if (sessionUid) {
|
|
|
|
|
return sessionUid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const findPrevious = (list, old) => {
|
|
|
|
|
const index = list.indexOf(old);
|
|
|
|
|
// If `old` was the first item in the list,
|
|
|
|
|
// choose the other item available:
|
|
|
|
|
return index ? list[index - 1] : list[1];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const findNextSessionUid = (state, group) => {
|
|
|
|
|
// If we're closing a root group (i.e. a whole tab),
|
|
|
|
|
// the next group needs to be a root group as well:
|
|
|
|
|
if (state.activeRootGroup === group.uid) {
|
|
|
|
|
const rootGroups = getRootGroups({termGroups: state});
|
|
|
|
|
const nextGroup = findPrevious(rootGroups, group);
|
|
|
|
|
return findFirstSession(state, nextGroup);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const {children} = state.termGroups[group.parentUid];
|
|
|
|
|
const nextUid = findPrevious(children, group.uid);
|
|
|
|
|
return findFirstSession(state, state.termGroups[nextUid]);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function ptyExitTermGroup(sessionUid) {
|
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
|
const {termGroups} = getState();
|
|
|
|
|
const group = findBySession(termGroups, sessionUid);
|
|
|
|
|
// This might have already been closed:
|
|
|
|
|
if (!group) {
|
|
|
|
|
return dispatch(ptyExitSession(sessionUid));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dispatch({
|
|
|
|
|
type: TERM_GROUP_EXIT,
|
|
|
|
|
uid: group.uid,
|
|
|
|
|
effect: () => {
|
|
|
|
|
const activeSessionUid = termGroups.activeSessions[termGroups.activeRootGroup];
|
|
|
|
|
if (Object.keys(termGroups.termGroups).length > 1 && activeSessionUid === sessionUid) {
|
|
|
|
|
const nextSessionUid = findNextSessionUid(termGroups, group);
|
|
|
|
|
dispatch(setActiveSession(nextSessionUid));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dispatch(ptyExitSession(sessionUid));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function userExitTermGroup(uid) {
|
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
|
const {termGroups} = getState();
|
|
|
|
|
dispatch({
|
|
|
|
|
type: TERM_GROUP_EXIT,
|
|
|
|
|
uid,
|
|
|
|
|
effect: () => {
|
|
|
|
|
const group = termGroups.termGroups[uid];
|
|
|
|
|
if (Object.keys(termGroups.termGroups).length <= 1) {
|
|
|
|
|
// No need to attempt finding a new active session
|
|
|
|
|
// if this is the last one we've got:
|
|
|
|
|
return dispatch(userExitSession(group.sessionUid));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const activeSessionUid = termGroups.activeSessions[termGroups.activeRootGroup];
|
|
|
|
|
if (termGroups.activeRootGroup === uid || activeSessionUid === group.sessionUid) {
|
|
|
|
|
const nextSessionUid = findNextSessionUid(termGroups, group);
|
|
|
|
|
dispatch(setActiveSession(nextSessionUid));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (group.sessionUid) {
|
|
|
|
|
dispatch(userExitSession(group.sessionUid));
|
|
|
|
|
} else {
|
|
|
|
|
group.children.forEach(childUid => {
|
|
|
|
|
dispatch(userExitTermGroup(childUid));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function exitActiveTermGroup() {
|
|
|
|
|
return (dispatch, getState) => {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: TERM_GROUP_EXIT_ACTIVE,
|
|
|
|
|
effect() {
|
|
|
|
|
const {sessions, termGroups} = getState();
|
|
|
|
|
const {uid} = findBySession(termGroups, sessions.activeUid);
|
|
|
|
|
dispatch(userExitTermGroup(uid));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|