Improve the run program command in vim
This commit is contained in:
parent
bc21059ea6
commit
05c46303c8
243
.vimrc
243
.vimrc
|
@ -689,8 +689,7 @@ fu! CreateCtags()
|
|||
" First determine if we're in a root drive directory. If we are then
|
||||
" we bail because we don't want to recurse across the entire drive!
|
||||
let l:path = expand('%:p:h')
|
||||
let l:path_without_slashes = substitute(l:path, "/", "", "g")
|
||||
if (strchars(l:path) - strchars(l:path_without_slashes)) <= 1
|
||||
if IsRootDrive(l:path)
|
||||
call PrintError("Not going to run ctags because the file is in a root drive directory")
|
||||
return
|
||||
endif
|
||||
|
@ -1037,6 +1036,34 @@ command -nargs=0 EditColorScheme call EditColorScheme()
|
|||
"|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
"|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
|
||||
fu! IsRootDrive(path) abort
|
||||
let l:path_without_slashes = substitute(a:path, "/", "", "g")
|
||||
return strchars(l:path_without_slashes) <= 1
|
||||
endfu
|
||||
|
||||
fu! IsPathContained(path1, path2) abort
|
||||
let l:normalized_path1 = substitute(fnamemodify(a:path1, ':p'), '\', '/', 'g')
|
||||
let l:normalized_path2 = substitute(fnamemodify(a:path2, ':p'), '\', '/', 'g')
|
||||
|
||||
" Ensure paths end with a directory separator
|
||||
if l:normalized_path1[-1:] != '/'
|
||||
let l:normalized_path1 .= '/'
|
||||
endif
|
||||
if l:normalized_path2[-1:] != '/'
|
||||
let l:normalized_path2 .= '/'
|
||||
endif
|
||||
|
||||
echo l:normalized_path1
|
||||
echo l:normalized_path2
|
||||
|
||||
return match(l:normalized_path1, '^' . escape(l:normalized_path2, '\')) != -1
|
||||
endfu
|
||||
|
||||
fu! CountChar(str, char) abort
|
||||
" Remove all characters that are not the target character.
|
||||
let l:filtered = substitute(a:str, '[^' . a:char . ']', '', 'g')
|
||||
return strlen(l:filtered)
|
||||
endfu
|
||||
|
||||
"##################################################################################
|
||||
" COMPILING CODE
|
||||
|
@ -1242,66 +1269,170 @@ fu! Build(optimized=0, silent=0)
|
|||
exec l:async_cmd . l:cmd
|
||||
endfu
|
||||
|
||||
fu! RunProgram()
|
||||
let l:ran = 0
|
||||
let l:ext = tolower(expand('%:e'))
|
||||
let l:path_to_use = ""
|
||||
|
||||
if l:ext == "jai"
|
||||
" Maybe the current file has an exe, i.e. wasn't compiled with a build script.
|
||||
if filereadable(expand('%:p:r') . '.exe')
|
||||
let l:ran = 1
|
||||
exec "AsyncRun! " . expand('%:p:r') . ".exe"
|
||||
elseif tolower(expand('%:h:t')) == "modules" || tolower(expand('%:h:h:t')) == "modules"
|
||||
" This is likely a jai module inside a project. We will want to do the exe/run script checks in the parent project folder.
|
||||
" The :h:h tests for a module inside a folder, e.g. modules/Basic/module.jai
|
||||
echo "module"
|
||||
if tolower(expand('%:h:t')) == "modules"
|
||||
let l:path_to_use = "/.."
|
||||
else
|
||||
let l:path_to_use = "/../.."
|
||||
endif
|
||||
endif
|
||||
elseif l:ext == "py"
|
||||
let l:ran = 1
|
||||
fu! RunProgram() abort
|
||||
if tolower(expand('%:e')) == "py"
|
||||
exec "AsyncRun! python %"
|
||||
return
|
||||
endif
|
||||
|
||||
if l:ran == 0
|
||||
" First check the current file's directory (and one directory back)
|
||||
" for a run script, falling back to the current working directory (and
|
||||
" one directory back) of the editor.
|
||||
if filereadable(expand('%:h') . '/run')
|
||||
echo "file here"
|
||||
exec "AsyncRun! " . expand('%:h') . "/run"
|
||||
elseif filereadable(expand('%:h') . '/../run')
|
||||
" Handles editing a file in a code/ or src/ and there's a run script one directory back.
|
||||
echo "file one back"
|
||||
exec "AsyncRun! " . expand('%:h') . "/../run"
|
||||
elseif filereadable("run")
|
||||
echo "cwd here"
|
||||
exec "AsyncRun! ./run"
|
||||
elseif filereadable("../run")
|
||||
" Handles editing a file in a code/ or src/ and there's a run script one directory back.
|
||||
echo "cwd one back"
|
||||
exec "AsyncRun! ../run"
|
||||
else
|
||||
" Final attempt is to run any exe that's found nearby.
|
||||
" We start with an exe relative to the open file's path.
|
||||
let l:files = systemlist('ls '.expand('%:h').''.l:path_to_use.'/*.exe 2>/dev/null')
|
||||
let l:file_exe_name = expand('%:t:r').'.exe' " Just the filename without the path
|
||||
|
||||
" Easy case is the current file has an exe with the same name in the
|
||||
" same directory. We run that if found.
|
||||
if filereadable(expand('%:p:h') . '/' . l:file_exe_name)
|
||||
exec 'AsyncRun! ' . expand('%:p:h') . '/' . l:file_exe_name
|
||||
return
|
||||
endif
|
||||
|
||||
" We start by looking for something to run relative to the current file's
|
||||
" path. If nothing is found then we start over looking in the current
|
||||
" working directory (the directory vim was opened in).
|
||||
let l:current_path = expand('%:p:h')
|
||||
|
||||
if !RunProgramInDirectory(l:current_path, l:file_exe_name)
|
||||
let l:cwd = getcwd()
|
||||
if !RunProgramInDirectory(l:cwd, l:file_exe_name)
|
||||
call PrintError("No exe or run script found in current file path '" . l:current_path . "' or working directory '". l:cwd ."'")
|
||||
endif
|
||||
endif
|
||||
endfu
|
||||
|
||||
|
||||
fu! RunProgramInDirectory(starting_path, file_exe_name) abort
|
||||
|
||||
let l:search_path = a:starting_path
|
||||
|
||||
if tolower(expand('%:e')) == "jai"
|
||||
" Check if we're editing inside a modules file and if so then get a
|
||||
" path that takes us outside of it. We'll use that path for finding an
|
||||
" exe or run script.
|
||||
let l:pos = match(l:search_path, "modules")
|
||||
if l:pos != -1
|
||||
" e.g. if the current path is
|
||||
" /z/jai/examples/wasm/modules/Blah/blah.jai then this is /z/jai/examples/wasm/
|
||||
let l:module_root_path = l:search_path[:l:pos-1]
|
||||
|
||||
" We don't want to proceed if the path is in the jai compiler's modules folder.
|
||||
let l:jai_path = tolower(g:campo_jai_path)
|
||||
if l:jai_path[-1:] != '/'
|
||||
let l:jai_path .= '/'
|
||||
endif
|
||||
|
||||
"echo 'modules root path: ' . l:module_root_path . ' | jai path: ' . l:jai_path
|
||||
if tolower(l:module_root_path) == l:jai_path
|
||||
"echo 'inside jai modules. Aborting run'
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:search_path = l:module_root_path
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:search_path = fnamemodify(l:search_path, ':p') " Normalize the path just in case.
|
||||
|
||||
" Search the current path for a run script, an exe with the current
|
||||
" filename, a bin/filename exe, a run_tree/filename exe - if nothing is
|
||||
" found then repeat one directory back when the current folder doesn't
|
||||
" contain a .git/ or it's not a root directory, e.g. /z/.
|
||||
"
|
||||
" If nothing is found after exhausting the search then we start over and
|
||||
" find the first exe with any name.
|
||||
|
||||
let l:current_path = l:search_path
|
||||
while 1
|
||||
" Run script has higher priority over an exe named after the current file.
|
||||
let l:search = l:current_path . 'run'
|
||||
if filereadable(l:search)
|
||||
exec "AsyncRun! " . l:search
|
||||
return 1
|
||||
endif
|
||||
|
||||
" filename exe
|
||||
let l:search = l:current_path . a:file_exe_name
|
||||
if filereadable(l:search)
|
||||
exec "AsyncRun! " . l:search
|
||||
return 1
|
||||
endif
|
||||
|
||||
" bin/filename exe
|
||||
let l:search = l:current_path . 'bin/' . a:file_exe_name
|
||||
if filereadable(l:search)
|
||||
exec "AsyncRun! " . l:search
|
||||
return 1
|
||||
endif
|
||||
|
||||
" run_tree/filename exe
|
||||
let l:search = l:current_path . 'run_tree/' . a:file_exe_name
|
||||
if filereadable(l:search)
|
||||
exec "AsyncRun! " . l:search
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Only go back a directory if the current path doesn't have a .git folder or we're not in a root drive path.
|
||||
if isdirectory(l:current_path . '.git') || IsRootDrive(l:current_path)
|
||||
break
|
||||
endif
|
||||
|
||||
let l:current_path = fnamemodify(l:current_path."../", ':p')
|
||||
endwhile
|
||||
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Start over but look for the first exe. The user will confirm if they
|
||||
" want to run it.
|
||||
"
|
||||
" @improve maybe provide the first 4 or 5 exes found and let them input
|
||||
" which one they want?
|
||||
|
||||
fu! GetFirstExePath(path)
|
||||
let l:files = systemlist('ls '.a:path.'*.exe 2>/dev/null')
|
||||
if len(l:files) > 0
|
||||
exec "AsyncRun! " . l:files[0]
|
||||
else
|
||||
" Last attempt is any exe in the current working directory.
|
||||
let l:files = systemlist('ls *.exe 2>/dev/null')
|
||||
if len(l:files) > 0
|
||||
exec "AsyncRun! " . l:files[0]
|
||||
else
|
||||
call PrintError("No exe or run script found!")
|
||||
return l:files[0]
|
||||
endif
|
||||
return ""
|
||||
endfu
|
||||
|
||||
let l:current_path = l:search_path
|
||||
let l:exe_to_confirm = ""
|
||||
|
||||
while 1
|
||||
let l:exe = GetFirstExePath(l:current_path)
|
||||
if l:exe != ""
|
||||
let l:exe_to_confirm = l:exe
|
||||
break
|
||||
endif
|
||||
|
||||
" bin/filename exe
|
||||
let l:exe = GetFirstExePath(l:current_path."bin/")
|
||||
if l:exe != ""
|
||||
let l:exe_to_confirm = l:exe
|
||||
break
|
||||
endif
|
||||
|
||||
" run_tree/filename exe
|
||||
let l:exe = GetFirstExePath(l:current_path."run_tree/")
|
||||
if l:exe != ""
|
||||
let l:exe_to_confirm = l:exe
|
||||
break
|
||||
endif
|
||||
|
||||
" Only go back a directory if the current path doesn't have a .git folder or we're not in a root drive path.
|
||||
if isdirectory(l:current_path . '.git') || IsRootDrive(l:current_path)
|
||||
break
|
||||
endif
|
||||
|
||||
let l:current_path = fnamemodify(l:current_path."../", ':p')
|
||||
endwhile
|
||||
|
||||
if l:exe_to_confirm != ""
|
||||
let l:confirm = confirm("Found exe ".l:exe_to_confirm." - run this?", "&Yes\n&No")
|
||||
if l:confirm == 1
|
||||
exec "AsyncRun! " . l:exe_to_confirm
|
||||
return 1
|
||||
endif
|
||||
redraw!
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfu
|
||||
|
||||
" Show results window the moment the async job starts
|
||||
|
@ -1528,9 +1659,9 @@ fu! RenameFile()
|
|||
if l:confirm == 1
|
||||
exec 'saveas' l:new_name
|
||||
exec 'silent! !rm' l:old_name
|
||||
endif
|
||||
endif
|
||||
redraw!
|
||||
endif
|
||||
endif
|
||||
endfu
|
||||
noremap <leader>n :call RenameFile()<cr>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user