about summary refs log tree commit diff stats
path: root/ranger/core
Commit message (Collapse)AuthorAgeFilesLines
...
* | Merge branch 'flat_command' of https://github.com/tex/rangerhut2014-12-051-7/+3
|\ \ | | | | | | | | | | | | | | | Conflicts: ranger/container/fsobject.py ranger/gui/widgets/browsercolumn.py
| * | fixes to flat commandMilan Svoboda2014-11-221-7/+3
| |/
* | core.actions: make the hardcoded linemode check more dynamichut2014-12-051-2/+3
| |
* | config/commands.py: added :default_linemode commandhut2014-12-051-0/+1
| |
* | core.fm: propagate papermanager_deep_search settinghut2014-12-031-0/+3
| |
* | reset papermanager cache when resetting fmhut2014-12-031-0/+2
| |
* | rename "title" linemode to "papertitle"hut2014-12-031-2/+2
| |
* | core.actions: map linemode "normal" to "filemode"hut2014-12-031-4/+8
| |
* | properly redrawhut2014-12-031-0/+4
| |
* | implement a paper managerhut2014-12-031-0/+2
| |
* | implement "permissions" linemodehut2014-12-031-2/+2
| |
* | allow setting a "linemode" for each file/directoryhut2014-12-031-0/+36
|/
* core.actions: Avoid UnicodeDecodeError, fixes #172hut2014-11-021-1/+2
| | | | Thanks to cym13 and GermainZ for looking into this
* implement flat commandMilan Svoboda2014-11-011-3/+7
|
* core.actions: fixed _MacroTemplate.idpatternhut2014-10-261-0/+1
| | | | | Thanks to trupanka for pointing out the problem at https://github.com/hut/ranger/issues/175
* change the bug tracker URLhut2014-08-221-1/+1
|
* fix crash in sha encode of previewsNathan Typanski2014-06-111-0/+3
| | | | | | | | | | | | | | | When opening certain filetypes, for which Ranger can't render a preview (they appear as 0 bytes), Ranger will crash on the sha1_encode: Traceback (most recent call last): File "~/ranger/ranger/core/main.py", line 139, in main cacheimg = os.path.join(ranger.CACHEDIR, self.sha1_encode(path)) File "~/ranger/ranger/core/actions.py", line 821, in sha1_encode sha1(path.encode('utf-8')).hexdigest()) + '.jpg' AttributeError: 'NoneType' object has no attribute 'encode' This solves that by checking at the beginning of get_preview() that `file.realpath` is not None, and returning early if it is None.
* Fix cdpath commit, which was broken in several waysAbdo Roig-Maranges2014-05-031-9/+5
| | | | | | | | | | | | This fixes commit 04681ff7ceb8a as follows: - check when cdpath is None. Otherwise split fails on None objects and causes ranger to crashes when CDPATH is not set in the environment. - actually set cdpath variable in the lowercase case. Before it was not assigned to any variable. - join paths with os.path.join instead of concatenating with '/'.
* Handle CDPATHCélestin Matte2014-04-281-0/+12
| | | | | | This shell feature allows one to cd directly to remote directories located in paths defined in the variable. Allow handling of such variable in ranger. Compatible with: bash, ksh, zsh, csh, and possibly others.
* core.actions: Enhanced :tab_new so you can type 5<C-n>hut2014-04-231-3/+4
|
* core.actions: Enhanced :tab_move so you can type 5gthut2014-04-231-1/+3
|
* Fix an erroneous function callEmanuel Guevel2014-04-131-1/+1
|
* Merge remote-tracking branch 'germain/w3m-previews' into w3m-previewshut2014-03-122-4/+40
|\
| * Add extensionGermainZ2014-03-091-2/+4
| |
| * Python2 fix for utf-8 characters in file pathsGermainZ2014-03-091-1/+9
| |
| * Allow scope.sh to be used for image previewsGermainZ2014-03-092-4/+30
| |
* | Merge branch 'master' of https://github.com/pkkm/rangerhut2014-02-151-1/+1
|\ \
| * | Strip leading whitespace when parsing configPaweł Kraśnicki2013-12-221-1/+1
| | |
* | | fix improper display of disk free size on os xintroom2013-12-281-1/+1
|/ /
* | core.actions: add numerical argument to toggle_visual_modehut2013-08-171-1/+3
| |
* | core.actions: better numerical argument to "mark_files"hut2013-08-171-1/+6
| |
* | Changed email address in source codehut2013-08-088-8/+8
| | | | | | | | | | Since lavabit.com ceased providing email services, I had to change my address from hut lavabit com to hut lepus uberspace de.
* | Merge branch 'efficient_w3mimgpreview'hut2013-07-281-0/+5
|\ \ | |/ |/|
| * core.fm: draw images laterhut2013-04-241-0/+2
| |
| * ext.img_display: more efficient way to draw imageshut2013-04-241-0/+3
| | | | | | | | | | | | | | | | Instead of loading up w3mimgdisplay for each image and killing it afterwards, we just open it once for the first image and keep it open. It can receive any number of commands, so we can just keep writing them into stdin. Perhaps it even caches the images to save time, I didn't test that yet.
* | core.fm: fix shell escaping when using feh + "open_all_images"hut2013-06-071-1/+1
| |
* | core.actions: update preview when changing file in pagerhut2013-05-011-0/+3
|/
* core.actions: reduce code dupliactionhut2013-04-241-12/+3
|
* core.actions: pressing "i" opens ui.pager, not ui.browser.pagerhut2013-04-241-3/+9
| | | | | | | ui.pager makes use of the whole width, ui.browser.pager "pushes" the main column away to the left. The former seems more efficient to me for the "i" key.
* core.action: make pager_move work in log too (key W)hut2013-04-241-1/+4
|
* config/commands: implemented :setintag <tags> <option>=<value>hut2013-04-201-2/+2
|
* Fix plugin names in log viewEmanuel Guevel2013-04-131-1/+1
|
* core.fm: disable garbage collecting old directorieshut2013-04-121-4/+4
| | | | it was kind of broken too
* core.fm: only apply open_all_files to cmds with $@hut2013-04-071-1/+2
|
* Add setting "open_all_images", removing "sxiv_opens_all_images"hut2013-03-061-11/+30
| | | | this is more general and can be adapted to work with more image viewers.
* core.fm: use "basename" instead of "path" in sxiv hookhut2013-03-051-3/+3
| | | | | This allows to pass more arguments before the argument list gets too long.
* added a rifle hook for better sxiv integrationhut2013-03-051-0/+19
|
* core.runner: dont switch to console when using "s" flaghut2013-03-041-0/+1
|
* core.fm: removed unnecessary importhut2013-03-041-1/+0
|
* renamed container.settingobject to container.settingshut2013-03-012-5/+4
| | | | | | | | | | ranger.container.settingobject.SettingObject -> ranger.container.settings.Settings ranger.container.settingobject.LocalSettingObject -> ranger.container.settings.LocalSettings This is for more conformity. No other class is called *Object.
<< end(); return result; } recipe tmp; slurp_body(in, tmp); if (is_waypoint(label)) After_fragments[label].steps.insert(After_fragments[label].steps.begin(), tmp.steps.begin(), tmp.steps.end()); else raise << "can't tangle after non-waypoint " << label << '\n' << end(); // End after Command Handler } //: after all recipes are loaded, insert fragments at appropriate labels. :(after "Begin Instruction Inserting/Deleting Transforms") Transform.push_back(insert_fragments); // NOT idempotent //: We might need to perform multiple passes, in case inserted fragments //: include more labels that need further insertions. Track which labels we've //: already processed using an extra field. :(before "End instruction Fields") mutable bool tangle_done; :(before "End instruction Constructor") tangle_done = false; :(code) void insert_fragments(const recipe_ordinal r) { insert_fragments(get(Recipe, r)); } void insert_fragments(recipe& r) { trace(101, "transform") << "--- insert fragments into recipe " << r.name << end(); bool made_progress = true; int pass = 0; while (made_progress) { made_progress = false; // create a new vector because insertions invalidate iterators vector<instruction> result; for (int i = 0; i < SIZE(r.steps); ++i) { const instruction& inst = r.steps.at(i); if (!inst.is_label || !is_waypoint(inst.label) || inst.tangle_done) { result.push_back(inst); continue; } inst.tangle_done = true; made_progress = true; Fragments_used.insert(inst.label); ostringstream prefix; prefix << '+' << r.name << '_' << pass << '_' << i; // ok to use contains_key even though Before_fragments uses [], // because appending an empty recipe is a noop if (contains_key(Before_fragments, inst.label)) { trace(102, "transform") << "insert fragments before label " << inst.label << end(); append_fragment(result, Before_fragments[inst.label].steps, prefix.str()); } result.push_back(inst); if (contains_key(After_fragments, inst.label)) { trace(102, "transform") << "insert fragments after label " << inst.label << end(); append_fragment(result, After_fragments[inst.label].steps, prefix.str()); } } r.steps.swap(result); ++pass; } } void append_fragment(vector<instruction>& base, const vector<instruction>& patch, const string prefix) { // append 'patch' to 'base' while keeping 'base' oblivious to any new jump // targets in 'patch' oblivious to 'base' by prepending 'prefix' to them. // we might tangle the same fragment at multiple points in a single recipe, // and we need to avoid duplicate jump targets. // so we'll keep jump targets local to the specific before/after fragment // that introduces them. set<string> jump_targets; for (int i = 0; i < SIZE(patch); ++i) { const instruction& inst = patch.at(i); if (inst.is_label && is_jump_target(inst.label)) jump_targets.insert(inst.label); } for (int i = 0; i < SIZE(patch); ++i) { instruction inst = patch.at(i); if (inst.is_label) { if (contains_key(jump_targets, inst.label)) inst.label = prefix+inst.label; base.push_back(inst); continue; } for (int j = 0; j < SIZE(inst.ingredients); ++j) { reagent& x = inst.ingredients.at(j); if (is_jump_target(x.name) && contains_key(jump_targets, x.name)) x.name = prefix+x.name; } base.push_back(inst); } } //: complain about unapplied fragments //: This can't run during transform because later (shape-shifting recipes) //: we'll encounter situations where fragments might get used long after //: they're loaded, and we might run transform_all in between. To avoid //: spurious errors, run this check right at the end, after all code is //: loaded, right before we run main. :(before "End Commandline Parsing") check_insert_fragments(); :(code) void check_insert_fragments() { for (map<string, recipe>::iterator p = Before_fragments.begin(); p != Before_fragments.end(); ++p) { if (!contains_key(Fragments_used, p->first)) raise << "could not locate insert before label " << p->first << '\n' << end(); } for (map<string, recipe>::iterator p = After_fragments.begin(); p != After_fragments.end(); ++p) { if (!contains_key(Fragments_used, p->first)) raise << "could not locate insert after label " << p->first << '\n' << end(); } } void test_tangle_before_and_after() { run( "def main [\n" " 1:num <- copy 0\n" " <label1>\n" " 4:num <- copy 0\n" "]\n" "before <label1> [\n" " 2:num <- copy 0\n" "]\n" "after <label1> [\n" " 3:num <- copy 0\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 0 in location 1\n" "mem: storing 0 in location 2\n" // label1 "mem: storing 0 in location 3\n" "mem: storing 0 in location 4\n" ); // nothing else CHECK_TRACE_COUNT("mem", 4); } void test_tangle_ignores_jump_target() { Hide_errors = true; run( "def main [\n" " 1:num <- copy 0\n" " +label1\n" " 4:num <- copy 0\n" "]\n" "before +label1 [\n" " 2:num <- copy 0\n" "]\n" ); CHECK_TRACE_CONTENTS( "error: can't tangle before non-waypoint +label1\n" ); } void test_tangle_keeps_labels_separate() { run( "def main [\n" " 1:num <- copy 0\n" " <label1>\n" " <label2>\n" " 6:num <- copy 0\n" "]\n" "before <label1> [\n" " 2:num <- copy 0\n" "]\n" "after <label1> [\n" " 3:num <- copy 0\n" "]\n" "before <label2> [\n" " 4:num <- copy 0\n" "]\n" "after <label2> [\n" " 5:num <- copy 0\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 0 in location 1\n" "mem: storing 0 in location 2\n" // label1 "mem: storing 0 in location 3\n" // 'after' fragments for earlier label always go before 'before' // fragments for later label "mem: storing 0 in location 4\n" // label2 "mem: storing 0 in location 5\n" "mem: storing 0 in location 6\n" ); // nothing else CHECK_TRACE_COUNT("mem", 6); } void test_tangle_stacks_multiple_fragments() { run( "def main [\n" " 1:num <- copy 0\n" " <label1>\n" " 6:num <- copy 0\n" "]\n" "before <label1> [\n" " 2:num <- copy 0\n" "]\n" "after <label1> [\n" " 3:num <- copy 0\n" "]\n" "before <label1> [\n" " 4:num <- copy 0\n" "]\n" "after <label1> [\n" " 5:num <- copy 0\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 0 in location 1\n" // 'before' fragments stack in order "mem: storing 0 in location 2\n" "mem: storing 0 in location 4\n" // label1 // 'after' fragments stack in reverse order "mem: storing 0 in location 5\n" "mem: storing 0 in location 3\n" "mem: storing 0 in location 6\n" ); // nothing CHECK_TRACE_COUNT("mem", 6); } void test_tangle_supports_fragments_with_multiple_instructions() { run( "def main [\n" " 1:num <- copy 0\n" " <label1>\n" " 6:num <- copy 0\n" "]\n" "before <label1> [\n" " 2:num <- copy 0\n" " 3:num <- copy 0\n" "]\n" "after <label1> [\n" " 4:num <- copy 0\n" " 5:num <- copy 0\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 0 in location 1\n" "mem: storing 0 in location 2\n" "mem: storing 0 in location 3\n" // label1 "mem: storing 0 in location 4\n" "mem: storing 0 in location 5\n" "mem: storing 0 in location 6\n" ); // nothing else CHECK_TRACE_COUNT("mem", 6); } void test_tangle_tangles_into_all_labels_with_same_name() { run( "def main [\n" " 1:num <- copy 10\n" " <label1>\n" " 4:num <- copy 10\n" " recipe2\n" "]\n" "def recipe2 [\n" " 1:num <- copy 11\n" " <label1>\n" " 4:num <- copy 11\n" "]\n" "before <label1> [\n" " 2:num <- copy 12\n" "]\n" "after <label1> [\n" " 3:num <- copy 12\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 10 in location 1\n" "mem: storing 12 in location 2\n" // label1 "mem: storing 12 in location 3\n" "mem: storing 10 in location 4\n" // recipe2 "mem: storing 11 in location 1\n" "mem: storing 12 in location 2\n" // label1 "mem: storing 12 in location 3\n" "mem: storing 11 in location 4\n" ); // nothing else CHECK_TRACE_COUNT("mem", 8); } void test_tangle_tangles_into_all_labels_with_same_name_2() { run( "def main [\n" " 1:num <- copy 10\n" " <label1>\n" " <label1>\n" " 4:num <- copy 10\n" "]\n" "before <label1> [\n" " 2:num <- copy 12\n" "]\n" "after <label1> [\n" " 3:num <- copy 12\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 10 in location 1\n" "mem: storing 12 in location 2\n" // label1 "mem: storing 12 in location 3\n" "mem: storing 12 in location 2\n" // label1 "mem: storing 12 in location 3\n" "mem: storing 10 in location 4\n" ); // nothing else CHECK_TRACE_COUNT("mem", 6); } void test_tangle_tangles_into_all_labels_with_same_name_3() { run( "def main [\n" " 1:num <- copy 10\n" " <label1>\n" " <foo>\n" " 4:num <- copy 10\n" "]\n" "before <label1> [\n" " 2:num <- copy 12\n" "]\n" "after <label1> [\n" " 3:num <- copy 12\n" "]\n" "after <foo> [\n" " <label1>\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 10 in location 1\n" "mem: storing 12 in location 2\n" // label1 "mem: storing 12 in location 3\n" "mem: storing 12 in location 2\n" // foo/label1 "mem: storing 12 in location 3\n" "mem: storing 10 in location 4\n" ); // nothing else CHECK_TRACE_COUNT("mem", 6); } void test_tangle_handles_jump_target_inside_fragment() { run( "def main [\n" " 1:num <- copy 10\n" " <label1>\n" " 4:num <- copy 10\n" "]\n" "before <label1> [\n" " jump +label2:label\n" " 2:num <- copy 12\n" " +label2\n" " 3:num <- copy 12\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 10 in location 1\n" // label1 "mem: storing 12 in location 3\n" "mem: storing 10 in location 4\n" ); // ignored by jump CHECK_TRACE_DOESNT_CONTAIN("mem: storing 12 in label 2"); // nothing else CHECK_TRACE_COUNT("mem", 3); } void test_tangle_renames_jump_target() { run( "def main [\n" " 1:num <- copy 10\n" " <label1>\n" " +label2\n" " 4:num <- copy 10\n" "]\n" "before <label1> [\n" " jump +label2:label\n" " 2:num <- copy 12\n" " +label2 # renamed\n" " 3:num <- copy 12\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 10 in location 1\n" // label1 "mem: storing 12 in location 3\n" "mem: storing 10 in location 4\n" ); // ignored by jump CHECK_TRACE_DOESNT_CONTAIN("mem: storing 12 in label 2"); // nothing else CHECK_TRACE_COUNT("mem", 3); } void test_tangle_jump_to_base_recipe() { run( "def main [\n" " 1:num <- copy 10\n" " <label1>\n" " +label2\n" " 4:num <- copy 10\n" "]\n" "before <label1> [\n" " jump +label2:label\n" " 2:num <- copy 12\n" " 3:num <- copy 12\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 10 in location 1\n" // label1 "mem: storing 10 in location 4\n" ); // ignored by jump CHECK_TRACE_DOESNT_CONTAIN("mem: storing 12 in label 2"); CHECK_TRACE_DOESNT_CONTAIN("mem: storing 12 in location 3"); // nothing else CHECK_TRACE_COUNT("mem", 2); } //: ensure that there are no new fragments created for a label after it's already been inserted to void test_new_fragment_after_tangle() { // define a recipe load("def foo [\n" " local-scope\n" " <label>\n" "]\n" "after <label> [\n" " 1:num/raw <- copy 34\n" "]\n"); transform_all(); CHECK_TRACE_DOESNT_CONTAIN_ERRORS(); Hide_errors = true; // try to tangle into recipe foo after transform load("before <label> [\n" " 2:num/raw <- copy 35\n" "]\n"); CHECK_TRACE_CONTAINS_ERRORS(); } :(before "End before Command Handler") if (contains_key(Fragments_used, label)) raise << "we've already tangled some code at label " << label << " in a previous call to transform_all(). Those locations won't be updated.\n" << end(); :(before "End after Command Handler") if (contains_key(Fragments_used, label)) raise << "we've already tangled some code at label " << label << " in a previous call to transform_all(). Those locations won't be updated.\n" << end();