@@ -3,18 +3,24 @@ package handler
3
3
import (
4
4
"bufio"
5
5
"bytes"
6
+ "context"
6
7
"errors"
7
8
"fmt"
8
9
"io"
9
10
"os"
10
11
"os/exec"
11
12
"path/filepath"
12
13
"strings"
14
+
15
+ "github.com/manifoldco/promptui"
13
16
)
14
17
18
+ var configFiles = []string {"./.tmux-sessionizer" , "~/.tmux-sessionizer" }
19
+
15
20
type ISessionHandler interface {
16
- NewSession () error
17
- GrabExistingSession () error
21
+ NewSession (ctx context.Context ) error
22
+ GrabExistingSession (ctx context.Context ) error
23
+ CreateNewProjectSession (ctx context.Context ) error
18
24
}
19
25
20
26
type SessionHandler struct {}
@@ -47,7 +53,6 @@ func (sh *SessionHandler) newTmuxCmd(name string, args ...string) *exec.Cmd {
47
53
}
48
54
49
55
func (sh * SessionHandler ) readConfig () * config {
50
- configFiles := []string {"./.tmux-sessionizer" , "~/.tmux-sessionizer" }
51
56
for _ , cf := range configFiles {
52
57
config , err := sh .parseConfig (cf )
53
58
if err == nil {
@@ -124,7 +129,7 @@ func (sh *SessionHandler) replaceHomeDir(fullpath string) (string, error) {
124
129
return strings .Replace (fullpath , home , "~" , 1 ), nil
125
130
}
126
131
127
- func (sh * SessionHandler ) NewSession () error {
132
+ func (sh * SessionHandler ) NewSession (ctx context. Context ) error {
128
133
config := sh .readConfig ()
129
134
if config == nil {
130
135
return errors .New ("failed to create new project from projects" )
@@ -209,7 +214,7 @@ func (sh *SessionHandler) toFzf(input bytes.Buffer) (bytes.Buffer, error) {
209
214
return fzfOut , nil
210
215
}
211
216
212
- func (sh * SessionHandler ) GrabExistingSession () error {
217
+ func (sh * SessionHandler ) GrabExistingSession (ctx context. Context ) error {
213
218
tmuxCmd := exec .Command ("tmux" , "list-sessions" , "-F" , "#{session_name}" )
214
219
var tmuxOut bytes.Buffer
215
220
tmuxCmd .Stdout = & tmuxOut
@@ -230,6 +235,85 @@ func (sh *SessionHandler) GrabExistingSession() error {
230
235
return nil
231
236
}
232
237
238
+ func (sh * SessionHandler ) CreateNewProjectSession (ctx context.Context ) error {
239
+ parentDirCandidatesSet := make (map [string ]struct {}, 0 )
240
+ for _ , configFile := range configFiles {
241
+ path , err := sh .expandPath (configFile )
242
+ if err != nil {
243
+ return fmt .Errorf ("failed to expand path: %w" , err )
244
+ }
245
+ file , err := os .Open (path )
246
+ if err != nil {
247
+ return fmt .Errorf ("failed to open config file: %w" , err )
248
+ }
249
+ defer file .Close ()
250
+
251
+ scanner := bufio .NewScanner (file )
252
+
253
+ for scanner .Scan () {
254
+ line := scanner .Text ()
255
+ if strings .HasPrefix (line , "default=" ) {
256
+ raw := strings .TrimPrefix (line , "default=" )
257
+ projects := strings .Split (raw , "," )
258
+ for _ , pr := range projects {
259
+ trimmed := strings .TrimSpace (pr )
260
+ parentDirCandidatesSet [trimmed ] = struct {}{}
261
+ }
262
+ }
263
+ }
264
+ }
265
+
266
+ parentDirCandidates := make ([]string , 0 )
267
+ for key , _ := range parentDirCandidatesSet {
268
+ parentDirCandidates = append (parentDirCandidates , key )
269
+ }
270
+
271
+ for {
272
+ chooseParentDirPrompt := promptui.Select {
273
+ Label : "Which project do you choose to create a new project (session) ?" ,
274
+ Items : parentDirCandidates ,
275
+ }
276
+ _ , parentDir , err := chooseParentDirPrompt .Run ()
277
+ if err != nil {
278
+ return fmt .Errorf ("failed to choose a parent directory: %w" , err )
279
+ }
280
+
281
+ newProjectNamePrompt := promptui.Prompt {
282
+ Label : "Enter a new project name" ,
283
+ }
284
+ newProjectName , err := newProjectNamePrompt .Run ()
285
+ if err != nil {
286
+ return fmt .Errorf ("failed to get a new project name: %w" , err )
287
+ }
288
+ newProjectPath , err := sh .expandPath (filepath .Join (parentDir , fmt .Sprintf ("%v/" , newProjectName )))
289
+ if err != nil {
290
+ return fmt .Errorf ("failed to expand path: %w" , err )
291
+ }
292
+ _ , err = os .Stat (newProjectPath )
293
+ if err == nil {
294
+ fmt .Printf ("%v is already exist\n " , newProjectPath )
295
+ continue
296
+ }
297
+ if os .IsNotExist (err ) {
298
+ if err := exec .Command ("mkdir" , "-p" , newProjectPath ).Run (); err != nil {
299
+ return fmt .Errorf ("failed to create a new project: %w" , err )
300
+ }
301
+ if sh .isInSession () {
302
+ return sh .switchToNewClient (newProjectName , newProjectPath )
303
+ }
304
+ if err := sh .newTmuxCmd (
305
+ "tmux" , "new-session" , "-s" ,
306
+ newProjectName , "-c" , newProjectPath ).Run (); err != nil {
307
+ return fmt .Errorf ("failed to create new session %w: " , err )
308
+ }
309
+ break
310
+ } else {
311
+ return fmt .Errorf ("failed to create a new project: %w" , err )
312
+ }
313
+ }
314
+ return nil
315
+ }
316
+
233
317
func (sh * SessionHandler ) isInSession () bool {
234
318
return len (os .Getenv ("TMUX" )) > 0
235
319
}
0 commit comments