Как добавить историю в строку редактирования?

Я пытаюсь добавить приложение истории в оболочку MacPorts. В настоящее время MacPorts использует историю, подобную bash, в которой история записывается после завершения сеанса. Это может быть проблематично, если сеанс выйдет из строя, поэтому я пытаюсь заставить оболочку MacPorts следовать примеру zsh. То есть, добавлять каждый элемент истории в файл по мере его выполнения.

В GNU readline эта функциональность тривиальна с функцией _ 1_. Однако MacPorts полагается на editline вместо этого. Библиотека строки редактирования, похоже, не имеет эквивалента для append_history, поэтому я немного не понимаю, что делать, чтобы добавить историю в файл. Я думал об использовании старых добрых стандартных функций, таких как fopen и fprintf, но понял, что строка редактирования использует свою собственную кодировку для строк истории (например, символ пробела переводится в восьмеричное \040). MacPorts должен быть совместим с этой кодировкой, поскольку строка редактирования используется в нескольких местах. Я предполагаю, что эта кодировка используется, потому что пробелы используются в качестве разделителя истории.

Я мог бы попытаться написать свои собственные функции, совместимые с этой кодировкой, но это чревато ненужными трудностями. Я чувствую, что что-то упускаю. Есть ли простой способ добавить историю в файл с помощью строки редактирования?


person GDP2    schedule 29.05.2018    source источник
comment
Посмотрите на функцию history(), она принимает аргумент, ev этот аргумент определяет операцию, которую будет выполнять функция, некоторые значения ev, которые могут оказаться полезными: H_APPEND для добавления char * в список истории и H_SAVE, который сохраняет список истории в указанный файл. Для справки это декларация истории int history(History *h, HistEvent *ev, int op, ...);, все это согласно man 3 editline   -  person xmonk    schedule 29.05.2018
comment
@xmonk Спасибо за отзыв. Я уже смотрел H_APPEND и так далее, но похоже, что он используется для добавления в список истории в памяти. Не для добавления в список истории на диске. Кроме того, H_SAVE, похоже, не поддерживает приложение. Я думаю, что он перезаписывает весь файл истории, поэтому он не кажется жизнеспособным для того, что я хочу.   -  person GDP2    schedule 29.05.2018


Ответы (1)


Что ж, решение в конечном итоге заключалось в том, чтобы использовать эти старые добрые стандартные функции. Мы также добавили в микс некоторую блокировку файлов, просто ради паранойи:

s = Tcl_GetString(objv[2]);
hist_file = fopen(s, "a");

flock(fileno(hist_file), LOCK_EX);
fprintf(hist_file, "%s\n", current_history()->line);
flock(fileno(hist_file), LOCK_UN);

fclose(hist_file);

Я подробно объяснил это здесь. Блокировка файлов была предложена на соответствующий PR. Это может быть не окончательная форма кода, но это то, что у нас есть до сих пор, и, вероятно, с этим мы будем работать. Если мы его изменим, вероятно, будет немного.

person GDP2    schedule 01.08.2018