diff --git a/dot_config/nushell/config.nu b/dot_config/nushell/config.nu index 391af3d..db90e62 100644 --- a/dot_config/nushell/config.nu +++ b/dot_config/nushell/config.nu @@ -1,264 +1,130 @@ -source ($nu.default-config-dir | path join 'themes.nu') - -# External completer example -# let carapace_completer = {|spans| -# carapace $spans.0 nushell ...$spans | from json -# } +source light_theme.nu +source dark_theme.nu +source xdg.nu $env.config = { - # true or false to enable or disable the welcome banner at startup + buffer_editor: null + color_config: $dark_theme + edit_mode: emacs + error_style: fancy + float_precision: 2 + footer_mode: 25 + recursion_limit: 50 + bracketed_paste: true + highlight_resolved_externals: true + use_ansi_coloring: true show_banner: false + render_right_prompt_on_last_line: false + use_kitty_protocol: false + + plugins: {} + + display_errors: { + exit_code: true + termination_signal: true + } ls: { - # use the LS_COLORS environment variable to colorize output use_ls_colors: true - # enable or disable clickable links. Your terminal has to support links. clickable_links: true } rm: { - # always act as if -t was given. Can be overridden with -p always_trash: false } table: { - # basic, compact, compact_double, light, thin, with_love, rounded, - # reinforced, heavy, none, other mode: light - # "always" show indexes, "never" show indexes, "auto" = show indexes - # when a table has "index" column index_mode: always - # show 'empty list' and 'empty record' placeholders for command output show_empty: true - # a left right padding of each column in a table - padding: { left: 1, right: 1 } - # show header text on separator/border line header_on_separator: false - # render footer in parent table if child is big enough - # (extended table option) footer_inheritance: false - # limit data rows from top and bottom after reaching a set point - # abbreviated_row_count: 10 + padding: { left: 1, right: 1 } trim: { - # wrapping or truncating methodology: wrapping - # A strategy used by the 'wrapping' methodology wrapping_try_keep_words: true - # A suffix used by the 'truncating' methodology - truncating_suffix: "…" + truncating_suffix: … } } - # "fancy" or "plain" for screen reader-friendly error messages - error_style: "fancy" - - # Whether an error message should be printed if an error of a certain - # kind is triggered. - display_errors: { - # assume the external command prints an error message - exit_code: true - # Core dump errors are always printed, and SIGPIPE never triggers an - # error. The setting below controls message printing for termination - # by all other signals. - termination_signal: true - } - - # datetime_format determines what a datetime rendered in the shell would - # look like. Behavior without this configuration point will be to - # "humanize" the datetime display, showing something like "a day ago." datetime_format: { - # shows up in displays of variables or other datetime's outside - # of tables # normal: '%a, %d %b %Y %H:%M:%S %z' - # generally shows up in tabular outputs such as ls. commenting this - # out will change it to the default human readable datetime format # table: '%m/%d/%y %I:%M:%S%p' } explore: { - status_bar_background: { fg: "#1D1F21", bg: "#C4C9C6" }, - command_bar_text: { fg: "#C4C9C6" }, - highlight: { fg: "black", bg: "yellow" }, + status_bar_background: { fg: "#1D1F21", bg: "#C4C9C6" } + command_bar_text: { fg: "#C4C9C6" } + highlight: { fg: black, bg: yellow } + selected_cell: { bg: light_blue } status: { - error: { fg: "white", bg: "red" }, + error: { fg: white, bg: red } warn: {} info: {} - }, - selected_cell: { bg: light_blue }, + } } history: { - # Session has to be reloaded for this to take effect max_size: 100_000 - # Enable to share history between multiple sessions, else you have to - # close the session to write history to file sync_on_enter: true - file_format: "sqlite" # "sqlite" or "plaintext" - - # only available with sqlite file_format. true enables history - # isolation, false disables it. true will allow the history to be - # isolated to the current session using up/down arrows. false will - # allow the history to be shared across all sessions. + file_format: sqlite isolation: false } completions: { - # set to true to enable case-sensitive completions case_sensitive: false - # set this to false to prevent auto-selecting completions when only - # one remains quick: true - # set this to false to prevent partial filling of the prompt partial: true - # prefix or fuzzy - algorithm: "prefix" - # "smart" (alphabetical for prefix matching, fuzzy score for - # fuzzy matching) or "alphabetical" - sort: "smart" - # set this to true to enable file/path/directory completions - # using LS_COLORS + algorithm: prefix + sort: smart use_ls_colors: true external: { - # set to false to prevent nushell looking into $env.PATH to find - # more suggestions, `false` recommended for WSL users as this look - # up may be very slow enable: true - # setting it lower can improve completion performance at the cost - # of omitting some options max_results: 100 - # check 'carapace_completer' above as an example completer: null } } filesize: { - # true => KB, MB, GB (ISO standard), false => KiB, MiB, GiB (Windows standard) metric: false - # b, kb, kib, mb, mib, gb, gib, tb, tib, pb, pib, eb, eib, auto - format: "auto" + format: auto } cursor_shape: { - # block, underscore, line, blink_block, blink_underscore, blink_line, - # inherit to skip setting cursor shape (line is the default) emacs: block - # block, underscore, line, blink_block, blink_underscore, blink_line, - # inherit to skip setting cursor shape (block is the default) vi_insert: block - # block, underscore, line, blink_block, blink_underscore, blink_line, - # inherit to skip setting cursor shape (underscore is the default) vi_normal: underscore } - # if you want a more interesting theme, you can replace the empty record - # with `$dark_theme`, `$light_theme` or another custom record - #color_config: $dark_theme - # if you want a more interesting theme, you can replace the empty record - # with `$dark_theme`, `$light_theme` or another custom record - color_config: $dark_theme - # always, never, number_of_rows, auto - footer_mode: 25 - # the precision for displaying floats in tables - float_precision: 2 - # command that will be used to edit the current line buffer with ctrl+o, - # if unset fallback to $env.VISUAL and $env.EDITOR - buffer_editor: null - use_ansi_coloring: true - # enable bracketed paste, currently useless on windows - bracketed_paste: true - # emacs, vi - edit_mode: emacs shell_integration: { - # osc2 abbreviates the path if in the home_dir, sets the tab/window - # title, shows the running command in the tab/window title osc2: true - # osc7 is a way to communicate the path to the terminal, this is - # helpful for spawning new tabs in the same directory osc7: true - # osc8 is also implemented as the deprecated setting - # ls.show_clickable_links, it shows clickable links in ls output if - # your terminal supports it. show_clickable_links is deprecated in - # favor of osc8 osc8: true - # osc9_9 is from ConEmu and is starting to get wider support. - # It's similar to osc7 in that it communicates the path to the terminal osc9_9: false - # osc133 is several escapes invented by Final Term which include the - # supported ones below. - # 133;A - Mark prompt start - # 133;B - Mark prompt end - # 133;C - Mark pre-execution - # 133;D;exit - Mark execution finished with exit code - # This is used to enable terminals to know where the prompt is, the - # command is, where the command finishes, and where the output of the - # command is osc133: true - # osc633 is closely related to osc133 but only exists in visual - # studio code (vscode) and supports their shell integration features - # 633;A - Mark prompt start - # 633;B - Mark prompt end - # 633;C - Mark pre-execution - # 633;D;exit - Mark execution finished with exit code - # 633;E - Explicitly set the command line with an optional nonce - # 633;P;Cwd= - Mark the current working directory and - # communicate it to the terminal - # and also helps with the run recent menu in vscode osc633: true - # reset_application_mode is escape \x1b[?1l and was added to help - # ssh work better reset_application_mode: true } - # true or false to enable or disable right prompt to be rendered on - # last line of the prompt. - render_right_prompt_on_last_line: false - # enables keyboard enhancement protocol implemented by kitty console, - # only if your terminal support this. - use_kitty_protocol: false - # true enables highlighting of external commands in the repl - # resolved by which. - highlight_resolved_externals: false - # the maximum number of times nushell allows recursion before stopping it - recursion_limit: 50 - - # Per-plugin configuration. - # See https://www.nushell.sh/contributor-book/plugins.html#configuration. - plugins: {} plugin_gc: { - # Configuration for plugin garbage c`ollection + plugins: {} default: { - # true to enable stopping of inactive plugins enabled: true - # how long to wait after a plugin is inactive to stop it stop_after: 10sec } - plugins: { - # alternate configuration for specific plugins, by name, for example: - # - # gstat: { - # enabled: false - # } - } } hooks: { - # run before the prompt is shown pre_prompt: [{ null }] - # run before the repl input is run pre_execution: [{ null }] + command_not_found: { null } + display_output: "if (term size).columns >= 100 { table -e } else { table }" env_change: { - # run if the PWD environment is different since the last repl input PWD: [{|before, after| null }] } - # run to display the output of a pipeline - display_output: "if (term size).columns >= 100 { table -e } else { table }" - # return an error message when a command is not found - command_not_found: { null } } menus: [ - # Configuration for default nushell menus - # Note the lack of source parameter { name: completion_menu only_buffer_difference: false @@ -293,7 +159,7 @@ $env.config = { padding: 0, border: true, cursor_offset: 0, - description_mode: "prefer_right" + description_mode: prefer_right min_description_width: 0 max_description_width: 50 max_description_height: 10 diff --git a/dot_config/nushell/env.nu b/dot_config/nushell/env.nu deleted file mode 100644 index 023b30b..0000000 --- a/dot_config/nushell/env.nu +++ /dev/null @@ -1,63 +0,0 @@ -# Nushell Environment Config File -# -# version = "0.100.0" - -$env.STARSHIP_SHELL = "nu" - -def create_left_prompt [] { - starship prompt --cmd-duration $env.CMD_DURATION_MS $'--status=($env.LAST_EXIT_CODE)' -} - -# Use nushell functions to define your right and left prompt -$env.PROMPT_COMMAND = { || create_left_prompt } -$env.PROMPT_COMMAND_RIGHT = "" - -$env.PROMPT_INDICATOR = "" -$env.PROMPT_INDICATOR_VI_INSERT = ": " -$env.PROMPT_INDICATOR_VI_NORMAL = "〉" -$env.PROMPT_MULTILINE_INDICATOR = "::: " - -# Specifies how environment variables are: -# - converted from a string to a value on Nushell startup (from_string) -# - converted from a value back to a string when running external commands (to_string) -# Note: The conversions happen *after* config.nu is loaded -$env.ENV_CONVERSIONS = { - "PATH": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } - "XDG_DATA_DIRS": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } - "Path": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } -} - -# Directories to search for scripts when calling source or use -# The default for this is $nu.default-config-dir/scripts -$env.NU_LIB_DIRS = [ - ($nu.default-config-dir | path join 'scripts') # add /scripts - ($nu.data-dir | path join 'completions') # default home for nushell completions -] - -# Directories to search for plugin binaries when calling register -# The default for this is $nu.default-config-dir/plugins -$env.NU_PLUGIN_DIRS = [ - # add /plugins - ($nu.default-config-dir | path join 'plugins') -] - -$env.PATH = [ - ($'($env.HOME)/.local/bin') - ($'($env.CARGO_HOME?)' | path join "bin") - ($'($env.HOME)/go/bin') - ($'($env.HOME)/.rbenv/shims') - ($'($env.HOME)/.local/share/JetBrains/Toolbox/scripts') - ...($env.PATH | split row (char esep)) - '/snap/bin' -] | each {|p| if ($p | path exists) { $p } else { null }} | uniq - -source ($nu.default-config-dir | path join 'xdg.nu') diff --git a/dot_config/nushell/env.nu.tmpl b/dot_config/nushell/env.nu.tmpl new file mode 100644 index 0000000..1773463 --- /dev/null +++ b/dot_config/nushell/env.nu.tmpl @@ -0,0 +1,116 @@ +# chezmoi:template:left-delimiter=#{{ +#{{- /* vim: set filetype=nu: */ -}} +# Nushell Environment Config File + +def command_prompt [] {( + starship prompt + $'--cmd-duration=($env.CMD_DURATION_MS)' + $'--status=($env.LAST_EXIT_CODE)' +)} + +def add_xdg [name ...parts] { + if $name in $env { + return ($env | get $name) + } + for $part in $parts { + let path = ($env.HOME | path join $part) + if ($path | path exists) { + return $path + } + } + return '' +} + +def from_string [] { + $in | split row (char esep) | path expand --no-symlink +} + +def to_string [] { + $in | path expand --no-symlink | str join (char esep) +} + +load-env { + XDG_BIN_HOME: (add_xdg XDG_BIN_HOME .local/bin) + XDG_CACHE_HOME: (add_xdg XDG_CACHE_HOME .cache) + XDG_CONFIG_HOME: (add_xdg XDG_CONFIG_HOME .config) + XDG_DATA_HOME: (add_xdg XDG_DATA_HOME .local/share) + XDG_INCLUDE_HOME: (add_xdg XDG_INCLUDE_HOME .local/include) + XDG_STATE_HOME: (add_xdg XDG_STATE_HOME .local/state) + + XDG_DESKTOP_DIR: (add_xdg XDG_DESKTOP_DIR desktop Desktop) + XDG_DOCUMENTS_DIR: (add_xdg XDG_DOCUMENTS_DIR documents Documents) + XDG_DOWNLOAD_DIR: (add_xdg XDG_DOWNLOAD_DIR downloads Downloads) + XDG_MUSIC_DIR: (add_xdg XDG_MUSIC_DIR music Music) + XDG_PICTURES_DIR: (add_xdg XDG_PICTURES_DIR pictures Pictures) + XDG_PODCAST_DIR: (add_xdg XDG_PODCAST_DIR podcasts Podcasts) + XDG_PUBLICSHARE_DIR: (add_xdg XDG_PUBLICSHARE_DIR public Public) + XDG_TEMPLATES_DIR: (add_xdg XDG_TEMPLATES_DIR templates Templates) + XDG_VIDEOS_DIR: (add_xdg XDG_VIDEOS_DIR videos Videos) +} + +load-env { + STARSHIP_SHELL: nu + EDITOR: nvim + + BROWSER: firefox + MAN_DIR: $'($env.XDG_DATA_HOME)/man/man1' + + BAT_PAGER: "less --raw-control-chars --quit-if-one-screen --no-init" + BAT_STYLE: plain + BAT_THEME: zenburn + MANPAGER: "sh -c 'col -bx | bat --language man --plain'" + CLICOLOR: 1 + GOPRIVATE: github.com/HelloTech + PULUMI_SKIP_UPDATE_CHECK: true + NPM_CONFIG_USERCONFIG: $'($env.XDG_CONFIG_HOME)/npm/npmrc' + RIPGREP_CONFIG_PATH: $'($env.XDG_CONFIG_HOME)/ripgrep/config' + + PATH: ([ + $env.XDG_BIN_HOME + ($'($env.CARGO_HOME?)' | path join "bin") + ($'($env.HOME)/go/bin') + ($'($env.HOME)/.rbenv/shims') + ($'($env.HOME)/.local/share/JetBrains/Toolbox/scripts') + '/usr/local/bin' + ...($env.PATH | split row (char esep)) + '/snap/bin' + ] | each {|p| if ($p | path exists) { $p } else { null }} + | uniq) + + PROMPT_COMMAND_RIGHT: "" + PROMPT_COMMAND: {|| command_prompt } + + PROMPT_INDICATOR: "" + PROMPT_INDICATOR_VI_INSERT: ": " + PROMPT_INDICATOR_VI_NORMAL: "〉" + PROMPT_MULTILINE_INDICATOR: "::: " + + NU_LIB_DIRS: [ + ($nu.default-config-dir | path join 'lib') + ($nu.data-dir | path join 'completions') + ] + + NU_PLUGIN_DIRS: [ + ($nu.default-config-dir | path join 'plugins') + ] + + ENV_CONVERSIONS: { + PATH: { + from_string: { from_string } + to_string: { to_string } + } + XDG_DATA_DIRS: { + from_string: { from_string } + to_string: { to_string } + } + Path: { + from_string: { from_string } + to_string: { to_string } + } + } +} + +hide add_xdg +hide command_prompt +hide from_string +hide to_string diff --git a/dot_config/nushell/lib/dark_theme.nu b/dot_config/nushell/lib/dark_theme.nu new file mode 100644 index 0000000..7ad6b7b --- /dev/null +++ b/dot_config/nushell/lib/dark_theme.nu @@ -0,0 +1,71 @@ +# For more information on defining custom themes, see +# https://www.nushell.sh/book/coloring_and_theming.html +# And here is the theme collection +# https://github.com/nushell/nu_scripts/tree/main/themes +let dark_theme = { + # color for nushell primitives + separator: white + # no fg, no bg, attr none effectively turns this off + leading_trailing_space_bg: { attr: n } + header: green_bold + empty: blue + # Closures can be used to choose colors for specific values. + # The value (in this case, a bool) is piped into the closure. + # eg) {|| if $in { 'light_cyan' } else { 'light_gray' } } + bool: light_cyan + int: white + filesize: cyan + duration: white + date: purple + range: white + float: white + string: white + nothing: white + binary: white + cell-path: white + row_index: green_bold + record: white + list: white + block: white + hints: dark_gray + search_result: { bg: red fg: white } + shape_and: purple_bold + shape_binary: purple_bold + shape_block: blue_bold + shape_bool: light_cyan + shape_closure: green_bold + shape_custom: green + shape_datetime: cyan_bold + shape_directory: cyan + shape_external: cyan + shape_externalarg: green_bold + shape_external_resolved: light_yellow_bold + shape_filepath: cyan + shape_flag: blue_bold + shape_float: purple_bold + # shapes are used to change the cli syntax highlighting + shape_garbage: { fg: white bg: red attr: b } + shape_glob_interpolation: cyan_bold + shape_globpattern: cyan_bold + shape_int: purple_bold + shape_internalcall: cyan_bold + shape_keyword: cyan_bold + shape_list: cyan_bold + shape_literal: blue + shape_match_pattern: green + shape_matching_brackets: { attr: u } + shape_nothing: light_cyan + shape_operator: yellow + shape_or: purple_bold + shape_pipe: purple_bold + shape_range: yellow_bold + shape_record: cyan_bold + shape_redirection: purple_bold + shape_signature: green_bold + shape_string: green + shape_string_interpolation: cyan_bold + shape_table: blue_bold + shape_variable: purple + shape_vardecl: purple + shape_raw_string: light_purple +} diff --git a/dot_config/nushell/lib/light_theme.nu b/dot_config/nushell/lib/light_theme.nu new file mode 100644 index 0000000..b7eec57 --- /dev/null +++ b/dot_config/nushell/lib/light_theme.nu @@ -0,0 +1,72 @@ +# For more information on defining custom themes, see +# https://www.nushell.sh/book/coloring_and_theming.html +# And here is the theme collection +# https://github.com/nushell/nu_scripts/tree/main/themes +let light_theme = { + # color for nushell primitives + separator: dark_gray + # no fg, no bg, attr none effectively turns this off + leading_trailing_space_bg: { attr: n } + header: green_bold + empty: blue + # Closures can be used to choose colors for specific values. + # The value (in this case, a bool) is piped into the closure. + # eg) {|| if $in { 'dark_cyan' } else { 'dark_gray' } } + bool: dark_cyan + int: dark_gray + filesize: cyan_bold + duration: dark_gray + date: purple + range: dark_gray + float: dark_gray + string: dark_gray + nothing: dark_gray + binary: dark_gray + cell-path: dark_gray + row_index: green_bold + record: dark_gray + list: dark_gray + block: dark_gray + hints: dark_gray + search_result: { fg: white bg: red } + shape_and: purple_bold + shape_binary: purple_bold + shape_block: blue_bold + shape_bool: light_cyan + shape_closure: green_bold + shape_custom: green + shape_datetime: cyan_bold + shape_directory: cyan + shape_external: cyan + shape_externalarg: green_bold + shape_external_resolved: light_purple_bold + shape_filepath: cyan + shape_flag: blue_bold + shape_float: purple_bold + # shapes are used to change the cli syntax highlighting + shape_garbage: { fg: white bg: red attr: b } + shape_glob_interpolation: cyan_bold + shape_globpattern: cyan_bold + shape_int: purple_bold + shape_internalcall: cyan_bold + shape_keyword: cyan_bold + shape_list: cyan_bold + shape_literal: blue + shape_match_pattern: green + shape_matching_brackets: { attr: u } + shape_nothing: light_cyan + shape_operator: yellow + shape_or: purple_bold + shape_pipe: purple_bold + shape_range: yellow_bold + shape_record: cyan_bold + shape_redirection: purple_bold + shape_signature: green_bold + shape_string: green + shape_string_interpolation: cyan_bold + shape_table: blue_bold + shape_variable: purple + shape_vardecl: purple + shape_raw_string: light_purple +} + diff --git a/dot_config/nushell/lib/xdg.nu b/dot_config/nushell/lib/xdg.nu new file mode 100644 index 0000000..68aadd1 --- /dev/null +++ b/dot_config/nushell/lib/xdg.nu @@ -0,0 +1,10 @@ +let xdg = $env + | transpose name value + | each {|e| if $e.name =~ 'XDG_' {{ + name: ($e.name | str replace 'XDG_' '' | str downcase), + value: $e.value + }} else { null }} + | reduce --fold {} {|e, memo| { + ...$memo, + $e.name: $e.value + }} diff --git a/dot_config/nushell/xdg.nu b/dot_config/nushell/xdg.nu deleted file mode 100644 index 05b5c6b..0000000 --- a/dot_config/nushell/xdg.nu +++ /dev/null @@ -1,27 +0,0 @@ -$env.XDG_BIN_HOME = $'($env.HOME)/.local/bin' -$env.XDG_CACHE_HOME = $'($env.HOME)/.cache' -$env.XDG_CONFIG_HOME = $'($env.HOME)/.config' -$env.XDG_DATA_HOME = $'($env.HOME)/.local/share' -$env.XDG_INCLUDE_HOME = $'($env.HOME)/.local/include' -$env.XDG_STATE_HOME = $'($env.HOME)/.local/state' - -$env.XDG_DESKTOP_DIR = $'($env.HOME)/desktop' -$env.XDG_DOCUMENTS_DIR = $'($env.HOME)/documents' -$env.XDG_DOWNLOAD_DIR = $'($env.HOME)/downloads' -$env.XDG_MUSIC_DIR = $'($env.HOME)/music' -$env.XDG_PICTURES_DIR = $'($env.HOME)/pictures' -$env.XDG_PODCAST_DIR = $'($env.HOME)/podcasts' -$env.XDG_PUBLICSHARE_DIR = $'($env.HOME)/public' -$env.XDG_TEMPLATES_DIR = $'($env.HOME)/templates' -$env.XDG_VIDEOS_DIR = $'($env.HOME)/videos' - -let xdg = $env - | transpose name value - | each {|e| if $e.name =~ 'XDG_' {{ - name: ($e.name | str replace 'XDG_' '' | str downcase), - value: $e.value - }} else { null }} - | reduce --fold {} {|e, memo| { - ...$memo, - $e.name: ($e.value | if $in =~ ':' { split row ':' } else { $e.value }) - }} diff --git a/dot_config/nvim/lua/core/config.lua b/dot_config/nvim/lua/core/config.lua index b946457..c2602e7 100644 --- a/dot_config/nvim/lua/core/config.lua +++ b/dot_config/nvim/lua/core/config.lua @@ -1,6 +1,7 @@ vim.g.mapleader = "," vim.g.maplocalleader = "," +vim.opt.shell = 'bash' vim.opt.fileformats = { "unix", "dos", "mac" } vim.opt.mouse = "a" diff --git a/dot_local/bin/executable_install-zig b/dot_local/bin/executable_install-zig index acca8ea..b99b06d 100755 --- a/dot_local/bin/executable_install-zig +++ b/dot_local/bin/executable_install-zig @@ -6,11 +6,11 @@ set -euo pipefail source "${XDG_DATA_HOME}/buddy-up/includes/utils.sh" APP=zig -VERSION=${VERSION:-0.14.0} +VERSION=${VERSION:-0.13.0} DEST=${XDG_DATA_HOME}/apps/releases/${APP} main() ( - URL=https://ziglang.org/builds/zig-linux-x86_64-${VERSION}-dev.2577+271452d22.tar.xz + URL=https://ziglang.org/download/${VERSION}/zig-$(get_os)-$(uname -m)-${VERSION}.tar.xz extract_tarball "${URL}" "${DEST}/${VERSION}" "--strip-components 1" set_current_link "${DEST}" "${VERSION}" set_link "${XDG_BIN_HOME}/${APP}" "${DEST}" "${APP}"