diff --git a/ChangeLog b/ChangeLog index 569a87bb..720cede8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2026.04.28, v19.15.0 + +feature: +- 9d97343b cloudcmd: operation: rm useless checks +- 46a88cfa cloudcmd: client: key: vim: cc, mm + +2026.04.28, v19.14.0 + +feature: +- 36a8b641 cloudcmd: ponse v8.0.0 +- 1c263c18 docker: io: /usr/src/cloudcmd -> /usr/local/share/cloudcmd +- ea7b828c docker: io: ubuntu: resolute +- cd6c11ac docker: io: far2l +- c4beeec6 docker: io: gdu: add + 2026.04.21, v19.13.1 feature: diff --git a/HELP.md b/HELP.md index 5deebdd0..a7ab6ea7 100644 --- a/HELP.md +++ b/HELP.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.13.1 +# Cloud Commander v19.15.0 ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] @@ -232,6 +232,8 @@ When the `--vim` option is provided, or the configuration parameter `vim` is set | `mf` | make file | `tt` | show terminal | `e` | edit file +| `cc` | copy +| `mm` | move Commands can be joined, for example: @@ -1115,6 +1117,8 @@ There are a lot of ways to be involved in `Cloud Commander` development: ## Version history +- *2026.04.28*, **[v19.15.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.15.0)** +- *2026.04.28*, **[v19.14.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.14.0)** - *2026.04.21*, **[v19.13.1](//github.com/coderaiser/cloudcmd/releases/tag/v19.13.1)** - *2026.04.15*, **[v19.13.0](//github.com/coderaiser/cloudcmd/releases/tag/v19.13.0)** - *2026.04.12*, **[v19.12.5](//github.com/coderaiser/cloudcmd/releases/tag/v19.12.5)** diff --git a/README.md b/README.md index 770d6c35..633084f5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Cloud Commander v19.13.1 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] +# Cloud Commander v19.15.0 [![Build Status][BuildStatusIMGURL]][BuildStatusURL] [![Codacy][CodacyIMG]][CodacyURL] [![Gitter][GitterIMGURL]][GitterURL] ### [Main][MainURL] [Blog][BlogURL] [Support][SupportURL] [Demo][DemoURL] diff --git a/client/key/vim/index.js b/client/key/vim/index.js index 5f67f4e4..a39bd894 100644 --- a/client/key/vim/index.js +++ b/client/key/vim/index.js @@ -60,6 +60,14 @@ const getOperations = (event, deps) => { remove: () => { Operation.show('delete'); }, + operationCopy: () => { + event.preventDefault(); + Operation.show('copy'); + }, + operationMove: () => { + event.preventDefault(); + Operation.show('move'); + }, makeDirectory: () => { event.stopImmediatePropagation(); diff --git a/client/key/vim/vim.js b/client/key/vim/vim.js index 0d0404c3..63452faa 100644 --- a/client/key/vim/vim.js +++ b/client/key/vim/vim.js @@ -40,6 +40,8 @@ export default (key, operations = {}) => { makeDirectory = noop, terminal = noop, edit = noop, + operationCopy = noop, + operationMove = noop, } = operations; if (key === 'Enter') @@ -111,6 +113,16 @@ export default (key, operations = {}) => { return end(); } + if (value === 'cc') { + operationCopy(); + return end(); + } + + if (value === 'mm') { + operationMove(); + return end(); + } + if (value === 'mf') { makeFile(); return end(); diff --git a/client/key/vim/vim.spec.js b/client/key/vim/vim.spec.js index 88cdd89e..02fd52d4 100644 --- a/client/key/vim/vim.spec.js +++ b/client/key/vim/vim.spec.js @@ -43,6 +43,28 @@ test('vim: ^', (t) => { t.end(); }); +test('vim: cc', (t) => { + const operationCopy = stub(); + + vim('cc', { + operationCopy, + }); + + t.calledWithNoArgs(operationCopy); + t.end(); +}); + +test('vim: mm', (t) => { + const operationMove = stub(); + + vim('mm', { + operationMove, + }); + + t.calledWithNoArgs(operationMove); + t.end(); +}); + test('vim: w', (t) => { const moveNext = stub(); diff --git a/client/modules/operation/set-listeners.js b/client/modules/operation/set-listeners.js index 431c7791..e54e7d14 100644 --- a/client/modules/operation/set-listeners.js +++ b/client/modules/operation/set-listeners.js @@ -15,15 +15,12 @@ export const setListeners = (options) => (emitter) => { } = options; let done; - let lastError; const onAbort = wraptile(({emitter, operation}) => { emitter.abort(); const msg = `${operation} aborted`; - lastError = true; - Dialog.alert(msg, { cancel: false, }); @@ -40,13 +37,10 @@ export const setListeners = (options) => (emitter) => { operation, })); - let noProgress = true; - const listeners = { progress: (value) => { done = value === 100; progress.setProgress(value); - noProgress = false; }, end: () => { @@ -54,13 +48,10 @@ export const setListeners = (options) => (emitter) => { forEachKey(removeListener, listeners); progress.remove(); - if (lastError || done || noProgress) - callback(); + callback(); }, error: async (error) => { - lastError = error; - if (noContinue) { listeners.end(error); Dialog.alert(error); diff --git a/docker/Dockerfile.io b/docker/Dockerfile.io index ffb27654..7ed5c8fe 100644 --- a/docker/Dockerfile.io +++ b/docker/Dockerfile.io @@ -3,11 +3,11 @@ FROM ubuntu:resolute LABEL maintainer="Coderaiser" LABEL org.opencontainers.image.source="https://github.com/coderaiser/cloudcmd" -RUN mkdir -p /usr/src/cloudcmd +RUN mkdir -p /usr/local/share/cloudcmd -WORKDIR /usr/src/cloudcmd +WORKDIR /usr/local/share/cloudcmd -COPY package.json /usr/src/cloudcmd/ +COPY package.json /usr/local/share/cloudcmd/ ENV DEBIAN_FRONTEND=noninteractive \ NVM_DIR=/usr/local/share/nvm \ @@ -58,6 +58,8 @@ RUN echo "> remove user" && \ bun r gritty --omit dev && \ bun i gritty --omit dev && \ bun pm cache rm && \ + echo "> setup cloudcmd" && \ + ln -s /usr/local/share/cloudcmd/bin/cloudcmd.js /usr/local/bin/cloudcmd && \ echo "> setup git" && \ git config --global core.whitespace -trailing-space && \ git config --global pull.rebase true && \ @@ -81,12 +83,13 @@ RUN echo "> remove user" && \ echo "el_GR.UTF-8 UTF-8" >> /etc/locale.gen && \ locale-gen -COPY . /usr/src/cloudcmd +COPY . /usr/local/share/cloudcmd WORKDIR / ENV cloudcmd_terminal=true \ cloudcmd_terminal_path=gritty \ + cloudcmd_vim=true \ cloudcmd_open=false \ PATH=node_modules/.bin:$PATH \ PATH=~/.local/bin:$PATH \ @@ -97,8 +100,6 @@ ENV cloudcmd_terminal=true \ LC_ALL=en_US.UTF-8 \ TERM=xterm-256color \ XDG_CACHE_HOME=/tmp \ - XDG_DATA_HOME=/usr/local/share + XDG_DATA_HOME=/usr/local/share EXPOSE 8000 -EXPOSE 8000 - -ENTRYPOINT ["/usr/src/cloudcmd/bin/cloudcmd.js"] +ENTRYPOINT ["/usr/local/share/cloudcmd/bin/cloudcmd.js"] diff --git a/package.json b/package.json index 1df08391..64d0befb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudcmd", - "version": "19.13.1", + "version": "19.15.0", "type": "module", "author": "coderaiser (https://github.com/coderaiser)", "description": "File manager for the web with console and editor", @@ -127,7 +127,7 @@ "open": "^11.0.0", "package-json": "^10.0.0", "pipe-io": "^4.0.1", - "ponse": "^7.0.0", + "ponse": "^8.0.0", "pullout": "^5.0.0", "putout": "^42.0.5", "redzip": "^4.6.1", diff --git a/server/cloudcmd.js b/server/cloudcmd.js index 773b6499..cc91559b 100644 --- a/server/cloudcmd.js +++ b/server/cloudcmd.js @@ -5,7 +5,7 @@ import fs from 'node:fs'; import {fullstore} from 'fullstore'; import currify from 'currify'; import apart from 'apart'; -import ponse from 'ponse'; +import * as ponse from 'ponse'; import {restafary} from 'restafary'; import restbox from 'restbox'; import {konsole} from 'console-io'; @@ -186,7 +186,7 @@ function cloudcmdMiddle({modules, config}) { const zip = apart(config, 'zip'); const root = apart(config, 'root'); - const ponseStatic = ponse.static({ + const ponseStatic = ponse.createStatic({ cache, root: DIR_ROOT, }); diff --git a/server/config.js b/server/config.js index db6f680d..77c4a6af 100644 --- a/server/config.js +++ b/server/config.js @@ -6,7 +6,7 @@ import currify from 'currify'; import wraptile from 'wraptile'; import {tryToCatch} from 'try-to-catch'; import pullout from 'pullout'; -import ponse from 'ponse'; +import * as ponse from 'ponse'; import jonny from 'jonny'; import jju from 'jju'; import writejson from 'writejson'; diff --git a/server/markdown/index.js b/server/markdown/index.js index d95cb62c..3f80ff03 100644 --- a/server/markdown/index.js +++ b/server/markdown/index.js @@ -2,7 +2,7 @@ import {callbackify} from 'node:util'; import {fileURLToPath} from 'node:url'; import {dirname} from 'node:path'; import pullout from 'pullout'; -import ponse from 'ponse'; +import {getQuery} from 'ponse'; import {read} from 'redzip'; import root from '../root.js'; import parse from './worker.js'; @@ -40,7 +40,7 @@ function parseName(query, name, rootDir) { } async function onGET(request, name, root) { - const query = ponse.getQuery(request); + const query = getQuery(request); const fileName = parseName(query, name, root); const stream = await read(fileName); const data = await pullout(stream); diff --git a/server/rest/index.js b/server/rest/index.js index bd9a0d2f..6a599ca4 100644 --- a/server/rest/index.js +++ b/server/rest/index.js @@ -8,7 +8,7 @@ import wraptile from 'wraptile'; import currify from 'currify'; import pullout from 'pullout'; import json from 'jonny'; -import ponse from 'ponse'; +import * as ponse from 'ponse'; import {copymitter} from 'copymitter'; import _moveFiles from '@cloudcmd/move-files'; import * as CloudFunc from '#common/cloudfunc'; diff --git a/server/route.js b/server/route.js index 1d887874..7844ce09 100644 --- a/server/route.js +++ b/server/route.js @@ -1,7 +1,7 @@ import {createRequire} from 'node:module'; import {extname} from 'node:path'; import * as _win32 from 'win32'; -import ponse from 'ponse'; +import * as ponse from 'ponse'; import {rendy} from 'rendy'; import format from 'format-io'; import currify from 'currify';